# 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 / Gitea, 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.* 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 Gitea as the default store. 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), Gitea (Forgejo- compatible in deployment). Further backends (GitHub, GitLab, Jira) are product growth, not yet implemented. - **CLI** (`issue` / `issue-core`) and **Python library** for direct backend use. - **REST** (`issue serve`, optional `[api]` extra): intentional create (`POST /issues/`), list/get/claim (`GET`/`PATCH /issues/`). - **Backend↔backend sync** via CLI (e.g. Gitea ↔ 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 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 Gitea 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 Gitea/ SQLite GitHub Forgejo 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).