issue-core/INTENT.md

231 lines
12 KiB
Markdown
Raw Normal View History

# INTENT — issue-core
## Why it exists
The Coulomb org coordinates work through **work records**: identified,
lifecycle-bearing artefacts authored as **repo files** (ADR-001), indexed by
state-hub, under a closed kind registry (`workplan`, `task`, `intake`,
`decision`, `engagement`, `register-entry`). That framework is defined in
`the-custodian/canon/standards/work-record-types_v0.1.md` and the founder-
reviewed architecture draft (`WorkOrchestrationArchitectureDraft.md` v0.2).
External issue trackers (Forgejo, GitHub, Jira, …) remain necessary
when a human counterparty, open-source workflow, or third-party process lives
there. They are **not** the fleet coordination substrate and are **not** a
work-record kind. Canon is explicit: *issue-core issues become external
projections only.* The self-hosted forge product is **Forgejo** only
(ACT-ADR-005); Gitea is not a supported second product or migration target.
issue-core exists so that, **when an external tracker is actually in use**,
the fleet has one backend-agnostic surface to project, query, and update
tracker issues — and (target) a durable **mapping** between:
| Side | Identity |
| --- | --- |
| Internal work record | **UUIDv7** (bookkeeping / mapping key) + **canonical name** for humans and agents (`ISSUE-WP-0005-T01`, …) |
| External issue | `(backend, external_id)` (+ URL) |
Without a connector layer, external-tracker access fragments across per-repo
API clients, ad hoc `gh`/`glab`/curl, agent-local integrations, and SaaS
calls with no stable back-reference to the work record.
## Honest history (pivot, 2026-07-20)
issue-core was originally built and documented as a **task landing zone**: a
single place where humans, activity-core, and agents filed work via CLI /
REST, with the self-hosted forge as the default store (product language then
said Gitea; the fleet forge is **Forgejo**). That framing contradicted
file-first work records and produced a live incident
(`daily-todo-md-stale-review` → IssueSink → Forgejo issues that were never
fleet work).
Architecture draft §4.2 and the work-record types standard (CUST-WP-0060)
retargeted purpose: **connector, not origin**. Capability (CRUD, backends,
REST, backend-to-backend sync) stays; product north star is projection and
mapping at the boundary.
## What it is
A **connector framework to external issue-tracking systems**, with a
pluggable-backend architecture. Issue-core is **not** part of the internal
execution loop.
### Shipped today
- **Tracker CRUD** on configured backends: create, read, update, close /
reopen, comment (and related label / assignee / milestone operations).
- **Backends:** local SQLite (offline store / cache), **Forgejo** (Gitea-
compatible API; Python module `issue_core.backends.gitea`, backend type
string `gitea`). Further backends (GitHub, GitLab, Jira) are product
growth, not yet implemented. Gitea is not a second supported product.
- **CLI** (`issue` / `issue-core`) and **Python library** for direct backend use.
- **REST** (`issue serve`, optional `[api]` extra): intentional **external
tracker** create (`POST /issues/`), list/get (`GET`/`PATCH /issues/`).
REST claim/list is for tracker issues already on a backend — **not** the
fleet ops claim queue (see below).
- **Backend↔backend sync** via CLI (e.g. Forgejo ↔ SQLite) — *not* the same as
work-record boundary sync below.
- **Optional intentional ingestion** of TaskSpec payloads for clients that
deliberately create tracker issues (not the fleet path for internal findings).
### Target connector (stage-3 work-record architecture)
- **Mapping store:** durable work-record **UUIDv7**`(backend, external_id)`,
resolvable also by canonical work-record id; design in
`docs/uuid-external-id-mapping.md`.
- **Project / link CLI and API:** project an existing work record outward, or
link an existing external issue; idempotent on active mapping.
- **Boundary sync (when enabled):** optional two-way, transclusion-like sync
*at the boundary* for fields needed by external collab. **Zero load** when
no mapping/integration is configured.
- **Extend TaskSpec** with optional `work_record_uuid` (and kind/id denorm);
do **not** overload `triggering_event_id` (activity lineage only).
- Optional work-record file back-reference (canon-owned field names), mirroring
hub `state_hub_*_id` write-back patterns.
Until an external integration is **switched on** for a given workflow, the
connector must add **no coordination load** to the internal loop.
## What it is NOT
- **Not the origin of work records.** Work records originate as repo files
(or schema-valid blocks in context) per ADR-001 and the work-record types
standard. issue-core does not create workplans, tasks, intake items,
decisions, engagements, or register entries as fleet artefacts.
- **Not a work-record kind.** Tracker issues are not registered in
`work-record-types`. Unmapped backend issues sit **outside** the work-record
spine; they are external artefacts for tracker UI collaboration until mapped
to a work-record UUID.
- **Not the internal execution / coordination loop.** Humans and agents
**claim and execute** on work records (harness / NATS / activity-core as
feeds). Fleet orientation is state-hub views over indexed files — not
Forgejo issue lists. (Avoid calling this “intake” when you mean claim/execute;
**`intake` is a work-record kind** for sparks/findings.)
- **Not the default home for automation findings.** Internal findings belong
as **`kind: intake`** (then **promotion** to task / workplan / decision /
engagement). They must not silently become Forgejo issues via IssueSink.
Emitter policy: activity-core **ACTIVITY-WP-0022** (from ISSUE-WP-0004-T05 /
CUST-WP-0060).
- **Not the fleet ops claim queue.** Internal scheduled automation
(FI daily brief, Binky rhythm, mail intake, …) **claim and execute** via
activity-core **`ops_run`** ([ACT-ADR-005](../activity-core/docs/adr/adr-005-ops-runs-vs-dev-work-records.md)).
issue-core does **not** provide that queue. `POST /issues/` creates or
links an **external tracker** issue only. The default activity-core sink
remains state-hub progress + `ops_run`**not** REST to issue-core for
Binky/FI. Do not poll issue-core as the primary automation loop.
ACT-ADR-005: *issue-cores correct role is a connector facade over
external trackers (Forgejo, GitHub, Jira, …). It is not the origin of
work records and not the default internal ops queue. Gitea is out of
scope for this fleet; the self-hosted forge is Forgejo.*
- **Not a second autonomy or budget model.** `lane`, `tags`, and budgets live
on the work record. Projections carry only what external collab needs
(title, body, agreed labels); they must not invent parallel lane/budget
semantics on Forgejo labels without explicit rules.
- **Not a project manager, spawn audit trail, event bus, notification
system, or workflow engine.** Plans and dependencies are workplan tooling;
spawn audit stays with emitters; NATS/hub own inter-service events;
notifications and approval chains live elsewhere. Tracker state machine
stays small (`open` / `in_progress` / `blocked` / `closed`).
### Boundary sync discipline
Fleet work-record **`status`** (e.g. task `wait → todo → progress → done |
cancel`) and tracker **`IssueState`** (`open` / `in_progress` / `blocked` /
`closed`) are **distinct vocabularies**. They must not be merged casually.
- Outward / inward projection uses **explicit mapping rules**.
- Inward changes never **silently mutate** ADR-001 work-record files without
a defined writer (see mapping design open questions).
- Backend↔backend CLI sync is orthogonal to work-record boundary sync.
## How it fits
```
Repo files (ADR-001 / work-record kinds) External collaboration
workplan · task · intake · decision · Counterparty, OSS, Jira, …
engagement · register-entry
│ fix-consistency: register, UUIDv7 write-back
v
+------------------+
| state-hub | read model + generated views (not mapping authority)
+------------------+
│ optional project / link when a tracker is switched on
v
+------------------+ UUIDv7 (+ canonical id) +------------------+
| work-record | <---- mapping (target) ------> | issue-core |
| source (+ opt. | ↔ (backend, external_id) | (connector) |
| back-ref) | +--------+---------+
+------------------+ |
+---------+----------+
| Backend router |
+---+------+------+--+
| | |
v v v
Forgejo SQLite GitHub
cache (planned)
```
**Primary fleet path (coordination):**
1. Author or promote a **work record** in a repo file (`kind` from the closed
registry; findings enter as **intake**, then promote).
2. `fix-consistency` indexes the record and write-backs UUIDv7.
3. Claim / execute against the work record (and hub views).
4. **Optionally**, issue-core **projects or links** the record to an external
tracker and records the mapping (target).
**Secondary path (direct tracker use):**
- Humans/agents use CLI/REST when deliberately operating on a backend
(tracker admin, pure external collab).
- Authenticated `POST /issues/` only when the product decision is “create an
**external** issue,” not “spawn fleet work.”
- Unmapped issues remain outside the work-record spine.
**Downstream:**
- Backend native UIs for external collaboration.
- state-hub for fleet lifecycle of *work records*, not of every issue-core row.
## Success looks like
- External trackers usable through one CLI/API without per-platform clients.
- When a work record is projected, UUIDv7 ↔ external-id mapping is durable and
resolvable by canonical name (once implemented).
- Fleet `status` and tracker state stay cleanly separated under explicit rules.
- Internal automation does **not** open Forgejo issues for findings that belong
as intake / promoted work records.
- Unmapped tracker issues are not mistaken for fleet work records.
- With no integration switched on, the connector adds no load to the internal
loop.
- Offline SQLite backend sync still works for tracker data when connectivity
returns.
## See also
- `SCOPE.md` — shipped inventory, product boundary, TaskSpec contract.
- `docs/uuid-external-id-mapping.md` — mapping design (not implemented).
- `docs/intent-work-record-alignment-review.md` — audit that drove this rewrite.
- `workplans/ISSUE-WP-0004-align-with-work-record-canon.md` — initial pivot.
- `workplans/ISSUE-WP-0005-connector-alignment-implementation.md` — close
shipped-scope gaps against this intent.
- `the-custodian/canon/standards/work-record-types_v0.1.md` — kind registry,
spine, identity, promotion.
- `the-custodian/research/WorkOrchestrationArchitectureDraft.md` §4.2 —
connector decision.
- `the-custodian/canon/architecture/adr-001-workplans-as-repo-artefacts.md`.
- activity-core **ACTIVITY-WP-0022** — IssueSink default policy (emitter side).
- activity-core **ACT-ADR-005** — ops runs vs work records; issue-core is not
the ops claim queue.
- `workplans/ISSUE-WP-0006-forgejo-only-projection-boundary.md` — Forgejo-only
product language and projection boundary.