docs: align issue-core with work-record connector role (ISSUE-WP-0004)
Retarget INTENT, SCOPE, README, ROADMAP, and agent docs from "task landing zone" to external-tracker connector per work-record canon and architecture draft §4.2. Add UUID↔external-id mapping design; mark ISSUE-WP-0004 finished and cross-file activity-core ACTIVITY-WP-0022 for IssueSink policy.
This commit is contained in:
parent
5e556028ab
commit
d60175c354
9 changed files with 760 additions and 226 deletions
212
INTENT.md
212
INTENT.md
|
|
@ -2,57 +2,105 @@
|
|||
|
||||
## 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.
|
||||
The Coulomb org collaborates through **external issue trackers** (Forgejo /
|
||||
Gitea, GitHub, Jira, …) when a human counterparty, open-source workflow, or
|
||||
third-party process requires it. Those systems are not the fleet's internal
|
||||
coordination substrate — that role belongs to **work records** authored as
|
||||
repo files (ADR-001) and indexed by state-hub.
|
||||
|
||||
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 exists so that, **when an external tracker is actually in use**,
|
||||
every actor can project, query, and update issues through one backend-agnostic
|
||||
interface — and so the fleet can keep a stable **mapping** between internal
|
||||
work-record identity (UUIDs) and external issue ids.
|
||||
|
||||
issue-core gives every actor — human or machine — one stable, observable place
|
||||
to file work, and one stable surface to consume work from.
|
||||
Without a connector layer, external-tracker access fragments across:
|
||||
- Per-repo Gitea / Forgejo API clients (siloed, no shared mapping)
|
||||
- Ad hoc `gh` / `glab` / curl scripts (untyped, unaudited)
|
||||
- Agent-local integrations (lost when the agent ends)
|
||||
- Direct SaaS API calls (rate-limited, off-network, no UUID back-reference)
|
||||
|
||||
issue-core gives humans and machines one stable surface to talk to external
|
||||
trackers, and (target shape) one place that records which internal work record
|
||||
projects to which external issue.
|
||||
|
||||
## Honest history (pivot, 2026-07-20)
|
||||
|
||||
issue-core was originally built and documented as a **task landing zone**: a
|
||||
single observable place where humans, activity-core, and agents filed work via
|
||||
CLI / REST / future NATS, with Gitea as the default store. That framing
|
||||
contradicted the fleet decision that work originates as **repo files** and
|
||||
that Forgejo issues are not the coordination mechanism.
|
||||
|
||||
The pivot was ratified while reviewing a live incident: activity-core's
|
||||
`daily-todo-md-stale-review` ActivityDefinition routed findings through
|
||||
`IssueSink` → issue-core → Forgejo, producing issues nobody was meant to see
|
||||
as fleet work. Founder-reviewed architecture draft §4.2
|
||||
(`the-custodian/research/WorkOrchestrationArchitectureDraft.md` v0.2,
|
||||
2026-07-20) and the work-record canon
|
||||
(`the-custodian/canon/standards/work-record-types_v0.1.md`, CUST-WP-0060)
|
||||
settled the role below. Capability (CRUD, backends, REST, sync) stays; the
|
||||
*purpose* is retargeted to connector, not origin.
|
||||
|
||||
## What it is
|
||||
|
||||
A **task lifecycle manager** with a pluggable-backend architecture.
|
||||
A **connector framework to external issue-tracking systems**, 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.
|
||||
- **Projection / CRUD**: create, read, update, close, and comment on issues in
|
||||
the configured backend (Gitea/Forgejo, SQLite offline cache, planned GitHub /
|
||||
GitLab / Jira).
|
||||
- **Mapping (target)**: maintain internal work-record UUID ↔ external issue id
|
||||
so a work record can carry a back-reference to its tracker projection
|
||||
(design: `docs/uuid-external-id-mapping.md`).
|
||||
- **Boundary sync**: two-way, transclusion-like sync *at the boundary* when
|
||||
collaboration runs through a third-party tracker — not as the internal
|
||||
execution loop.
|
||||
- **CLI + REST**: human and automation surfaces for direct backend use when a
|
||||
tracker is intentionally switched on.
|
||||
- **Optional ingestion**: `POST /issues/` remains for authenticated clients that
|
||||
deliberately create tracker issues; it is **not** the primary fleet path for
|
||||
internal findings or work origin.
|
||||
|
||||
Backends today: **local SQLite**, **Gitea**. Planned: **GitHub**, **GitLab**, **JIRA**.
|
||||
|
||||
The CLI entry points are `issue` (primary) and `issue-core` (explicit alias).
|
||||
|
||||
Until an external integration is actually switched on for a given workflow, the
|
||||
connector layer should add **zero load** to the internal coordination loop.
|
||||
|
||||
## 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 the origin of work records.** Work records originate as repo files per
|
||||
ADR-001 (`the-custodian/canon/architecture/adr-001-workplans-as-repo-artefacts.md`
|
||||
and the work-record types standard). issue-core provides the
|
||||
**external-tracker projection** when one is in use. Internal tasks, intake
|
||||
items, workplans, and decisions are not created here.
|
||||
|
||||
- **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 the internal execution / coordination loop.** Claiming and execution
|
||||
run on work records directly (harness intake via NATS/activity-core per its
|
||||
stated target). Fleet orientation is state-hub + repo files, not Forgejo
|
||||
issue lists.
|
||||
|
||||
- **Not a project manager.** Phases, campaigns, milestones spanning multiple
|
||||
tasks, dependency graphs across tasks, gantt-style scheduling — that is the
|
||||
domain of workplans / project tooling. issue-core deals in individual
|
||||
external issues, not in plans composed of tasks.
|
||||
|
||||
- **Not a spawn audit trail.** When an upstream service deliberately emits an
|
||||
issue here, the *spawn event* belongs to the emitter (e.g. activity-core's
|
||||
`task_spawn_log`). issue-core stores the resulting issue and optional
|
||||
traceability fields (`triggering_event_id`, future work-record UUID) — not
|
||||
the audit-of-creation.
|
||||
|
||||
- **Not an event bus.** Communication between services flows over NATS (and
|
||||
state-hub progress events). issue-core consumes events, but does not relay them.
|
||||
state-hub progress events). issue-core consumes or serves specific
|
||||
boundaries; it does not relay events between other services.
|
||||
|
||||
- **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 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
|
||||
|
|
@ -61,56 +109,72 @@ issue-core is intentionally narrow. The following live elsewhere:
|
|||
## 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|
|
||||
+------+ +-----+ +------+
|
||||
Work records (repo files, ADR-001) External collaboration
|
||||
───────────────────────────────── ──────────────────────
|
||||
workplan / task / intake / … Counterparty, OSS, Jira, …
|
||||
│ │
|
||||
│ optional project when │
|
||||
│ a tracker is switched on │
|
||||
v v
|
||||
+------------------+ UUID ↔ issue id +------------------+
|
||||
| state-hub | <---- mapping ------> | issue-core |
|
||||
| (read model) | | (connector) |
|
||||
+------------------+ +--------+---------+
|
||||
|
|
||||
+---------+----------+
|
||||
| Backend router |
|
||||
+---+------+------+--+
|
||||
| | |
|
||||
v v v
|
||||
+------+ +-----+ +------+
|
||||
|Gitea | |SQLite| |GitHub|
|
||||
|Forgejo| |cache| | … |
|
||||
+------+ +-----+ +------+
|
||||
|
||||
Direct use (human CLI / intentional REST) still goes to issue-core
|
||||
without creating a work-record origin — useful for tracker admin and
|
||||
collaboration, not for fleet task birth.
|
||||
```
|
||||
|
||||
**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.
|
||||
**Primary fleet path (coordination):**
|
||||
1. A work record exists in a repo file (or is registered from one).
|
||||
2. Humans/agents claim and execute against that record (and state-hub views).
|
||||
3. **Optionally**, issue-core projects the record to an external tracker and
|
||||
records the UUID ↔ external-id mapping.
|
||||
|
||||
**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.
|
||||
**Secondary path (direct tracker use):**
|
||||
- **Humans** — `$ issue create ...` when deliberately working in a backend.
|
||||
- **Authenticated automation** — `POST /issues/` only when the product decision
|
||||
is "create an external issue," not "spawn fleet work."
|
||||
- **activity-core IssueSink** — must not be the default always-on path for
|
||||
internal findings (see ISSUE-WP-0004-T05 / activity-core follow-up).
|
||||
|
||||
**Downstream:**
|
||||
- Backend native UIs (Gitea web, GitHub, …) for external collaboration.
|
||||
- state-hub for fleet lifecycle visibility of *work records*, not of every
|
||||
issue-core row.
|
||||
|
||||
## 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.
|
||||
- External trackers are usable through one CLI/API without each agent learning
|
||||
platform-specific clients.
|
||||
- When a work record is projected outward, the UUID ↔ external-id mapping is
|
||||
durable and inspectable (once implemented per the design note).
|
||||
- Internal automation does **not** silently open Forgejo issues for findings
|
||||
that belong in repo work records.
|
||||
- Offline SQLite work syncs cleanly to a remote backend when connectivity
|
||||
returns.
|
||||
- With no external integration switched on, issue-core adds no load to the
|
||||
internal loop.
|
||||
|
||||
## See also
|
||||
|
||||
- `SCOPE.md` — concrete in/out-of-scope decisions and integration boundaries.
|
||||
- `ROADMAP.md` — feature trajectory.
|
||||
- `workplans/` — active workplans.
|
||||
- activity-core `docs/adr/adr-001-event-bridge-architecture.md` — the IssueSink
|
||||
contract that issue-core honors at `POST /issues/`.
|
||||
- `ROADMAP.md` — feature trajectory (connector-aligned).
|
||||
- `docs/uuid-external-id-mapping.md` — design for the mapping surface.
|
||||
- `workplans/ISSUE-WP-0004-align-with-work-record-canon.md` — this pivot.
|
||||
- `the-custodian/canon/standards/work-record-types_v0.1.md` — work-record canon.
|
||||
- `the-custodian/research/WorkOrchestrationArchitectureDraft.md` §4.2 —
|
||||
founder-reviewed connector role.
|
||||
- activity-core `docs/adr/adr-001-event-bridge-architecture.md` — IssueSink
|
||||
contract at `POST /issues/` (optional, intentional use only).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue