diff --git a/INTENT.md b/INTENT.md index 9afd85a..14bc3eb 100644 --- a/INTENT.md +++ b/INTENT.md @@ -2,179 +2,206 @@ ## Why it exists -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. +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**, -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. +the fleet has one backend-agnostic surface to project, query, and update +tracker issues — and (target) a durable **mapping** between: -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) +| 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) | -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. +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 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. +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). -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. +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. +pluggable-backend architecture. Issue-core is **not** part of the internal +execution loop. -Responsibilities: -- **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. +### Shipped today -Backends today: **local SQLite**, **Gitea**. Planned: **GitHub**, **GitLab**, **JIRA**. +- **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). -The CLI entry points are `issue` (primary) and `issue-core` (explicit alias). +### Target connector (stage-3 work-record architecture) -Until an external integration is actually switched on for a given workflow, the -connector layer should add **zero load** to the internal coordination loop. +- **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 -issue-core is intentionally narrow. The following live elsewhere: +- **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 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 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.** 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 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 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 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 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 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 an event bus.** Communication between services flows over NATS (and - state-hub progress events). issue-core consumes or serves specific - boundaries; it does not relay events between other services. +- **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`). -- **Not a notification system.** Surfacing "your task changed" to humans is - the job of the relevant UI / digest / chatbot layer, not issue-core. +### Boundary sync discipline -- **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. +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 ``` - 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. + 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. 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. + +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** — `$ 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). + +- 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 (Gitea web, GitHub, …) for external collaboration. -- state-hub for fleet lifecycle visibility of *work records*, not of every - issue-core row. + +- 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 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 +- 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. -- 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 (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. +- `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 — - founder-reviewed connector role. -- activity-core `docs/adr/adr-001-event-bridge-architecture.md` — IssueSink - contract at `POST /issues/` (optional, intentional use only). + connector decision. +- `the-custodian/canon/architecture/adr-001-workplans-as-repo-artefacts.md`. +- activity-core **ACTIVITY-WP-0022** — IssueSink default policy (emitter side). diff --git a/SCOPE.md b/SCOPE.md index d963a4f..62a8e78 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -303,14 +303,16 @@ workplans/ # ADR-001 work items for this repo ## 6. See also -- `INTENT.md` — why the connector role exists and the 2026-07-20 pivot +- `INTENT.md` — why the connector role exists (work-record-aligned rewrite 2026-07-22) - `README.md` — operator quick start - `ROADMAP.md` — phased growth (auto-config, mapping implementation, backends) - `docs/uuid-external-id-mapping.md` — mapping design (not implemented) +- `docs/intent-work-record-alignment-review.md` — INTENT vs work-record audit - `docs/nats-task-ingestion.md` — NATS design stub - `docs/argocd-gitops.md` — railiance01 deploy - `AGENT_INTEGRATION.md` — library patterns for tracker ops -- `workplans/ISSUE-WP-0004-align-with-work-record-canon.md` — framing alignment +- `workplans/ISSUE-WP-0004-align-with-work-record-canon.md` — initial framing pivot +- `workplans/ISSUE-WP-0005-connector-alignment-implementation.md` — implement mapping + close scope gaps - `the-custodian/canon/standards/work-record-types_v0.1.md` — work-record kinds (issue-core issues = external projections only) - `the-custodian/research/WorkOrchestrationArchitectureDraft.md` §4.2 diff --git a/docs/intent-work-record-alignment-review.md b/docs/intent-work-record-alignment-review.md index 3c586bf..e073b92 100644 --- a/docs/intent-work-record-alignment-review.md +++ b/docs/intent-work-record-alignment-review.md @@ -322,8 +322,17 @@ honesty without becoming a second inventory. - connector responsibilities already delivered, - or “stop IssueSink” without a named intake/promotion destination. -**Suggested next step:** apply the P1/P2 INTENT edits in a small docs PR (or -follow-up session); keep this report as the audit trail. +**Suggested next step (superseded):** apply the P1/P2 INTENT edits… + +### Remediation (2026-07-22) + +| Item | Status | +| --- | --- | +| P1–P3 INTENT edits (shipped vs target, diagram, dual lifecycle, UUIDv7 + canonical id, intake+promotion, unmapped outside spine, kind registry, claim/execute wording) | **Done** — `INTENT.md` rewritten 2026-07-22 | +| Implementation of mapping / scope gaps | **Tracked** — `workplans/ISSUE-WP-0005-connector-alignment-implementation.md` | + +This report remains the audit trail; treat INTENT as current intent, not the +pre-remediation text analyzed above. --- diff --git a/workplans/ISSUE-WP-0005-connector-alignment-implementation.md b/workplans/ISSUE-WP-0005-connector-alignment-implementation.md new file mode 100644 index 0000000..cf2ee15 --- /dev/null +++ b/workplans/ISSUE-WP-0005-connector-alignment-implementation.md @@ -0,0 +1,266 @@ +--- +id: ISSUE-WP-0005 +type: workplan +title: "Implement connector alignment: mapping, docs hygiene, scope gaps vs refined INTENT" +domain: infotech +repo: issue-core +status: proposed +owner: codex +topic_slug: infotech +created: "2026-07-22" +updated: "2026-07-22" +--- + +# Implement connector alignment: mapping, docs hygiene, scope gaps vs refined INTENT + +## Origin + +ISSUE-WP-0004 retargeted issue-core’s **docs framing** (connector, not landing +zone) and produced a mapping **design** only. A follow-up audit +(`docs/intent-work-record-alignment-review.md`) found no hard north-star +collision with the work-record framework, but soft frictions (identity, +diagram, dual lifecycles, shipped vs target). **INTENT.md was rewritten +2026-07-22** to absorb those recommendations. + +**This workplan implements the refined intention against current SCOPE:** the +shipped product is still a pre-canon CRUD + TaskSpec shell; the work-record- +aware connector (mapping, project/link, boundary-sync discipline, packaging +hygiene) is not built. Cross-repo emitter policy remains ACTIVITY-WP-0022. + +## Goal + +Close the gap between: + +| Layer | State at start of this WP | +| --- | --- | +| **INTENT** | Work-record-aligned connector (2026-07-22) | +| **SCOPE §1 shipped** | Models, SQLite/Gitea, CLI, REST TaskSpec, backend sync | +| **SCOPE §1.8 / target** | Mapping store/API, boundary sync, work_record_uuid, dual-lifecycle rules | + +Deliver a **minimum viable connector core**: durable mapping + project/link +surface + schema extension + status-mapping policy + doc/package hygiene — +without turning issue-core back into a work origin or fleet task board. + +## Non-goals + +- Originating workplans/tasks/intake in this service. +- Replacing activity-core IssueSink policy implementation (track/coordinate + ACTIVITY-WP-0022; do not duplicate). +- Full CRDT comment merge or multi-tracker fan-out. +- Auto-config from git remotes (ROADMAP Phase 1 — separate). +- GitHub/GitLab/Jira backends (unless a task explicitly needs a stub for + mapping tests — prefer fake/local backend). + +## Dependencies + +- INTENT.md + SCOPE.md (2026-07-21/22) + `docs/uuid-external-id-mapping.md` +- Work-record canon: `the-custodian/canon/standards/work-record-types_v0.1.md` +- Architecture §4.2 +- activity-core ACTIVITY-WP-0022 (emitter default; may complete in parallel) +- Optional later: canon PR for work-record YAML back-reference field names + +## Tasks + +## Task: Freeze intent/scope cross-links and residual doc hygiene + +```task +id: ISSUE-WP-0005-T01 +status: todo +priority: high +``` + +Ensure INTENT, SCOPE, README “See also”, and the alignment review all point at +the refined INTENT and this workplan. Update `docs/intent-work-record- +alignment-review.md` with a short “Remediation” note (INTENT rewrite done; +implementation tracked here). No new product claims. + +**Acceptance:** Cross-links consistent; review file marks INTENT remediation +done; no reintroduction of landing-zone language in those files. + +## Task: Packaging and capability framing cleanup + +```task +id: ISSUE-WP-0005-T02 +status: todo +priority: medium +``` + +Align packaging/metadata with connector intent (not “authoritative task +lifecycle manager” / multi-agent coordination board): + +- `pyproject.toml` description / keywords / long description if present +- `registry/capabilities/capability.infotech.issue-tracking.md` and + `CAPABILITY-issue-tracking.yaml` discovery text +- `AGENT_INTEGRATION.md` intro + top-level guidance (prefer work records; + use issue-core for external trackers) + +**Acceptance:** Grep for “landing zone”, “tasks land”, “authoritative task +lifecycle” in package/capability/agent docs is clean or historical-only; +capability summary matches SCOPE §1 honesty. + +## Task: Specify dual-lifecycle and projection field rules (normative note) + +```task +id: ISSUE-WP-0005-T03 +status: todo +priority: high +``` + +Turn INTENT’s boundary-sync discipline into an implementable policy doc under +`docs/` (e.g. `docs/boundary-sync-and-status-mapping.md`): + +- Table: work-record task/intake/… `status` ↔ optional tracker `IssueState` + (default: **outward status projection rules**; inward is suggest-only / + no silent file write in v1) +- Fields that may project (title, body, agreed labels) vs stay on work record + only (`lane`, tags policy, budgets, owner spine) +- Explicit: unmapped issues outside spine; mapping keys UUIDv7; canonical id + for operator UX + +**Acceptance:** Doc reviewed against work-record types standard; referenced +from SCOPE §2 and mapping design; ready to drive T04–T06 without re-litigating +policy. + +## Task: Implement mapping store (local SQLite) + +```task +id: ISSUE-WP-0005-T04 +status: todo +priority: high +``` + +Per `docs/uuid-external-id-mapping.md`: + +- Table `work_record_issue_map` (or equivalent) on local backend / dedicated + store used even when CRUD backend is Gitea +- Uniqueness: active `(backend, external_id)` and active + `(work_record_uuid, backend)` +- Domain service `MappingService`: upsert, resolve by UUID, by canonical id + (if provided), by external id, detach +- Unit tests for idempotent project and uniqueness + +**Acceptance:** Tests pass without a live Gitea; store survives reconnect; +SCOPE §1.8 “mapping store” can move toward shipped with an honest partial +note until CLI/API land. + +## Task: Project / link CLI (+ optional REST) + +```task +id: ISSUE-WP-0005-T05 +status: todo +priority: high +``` + +Ship operator surface: + +- `issue project …` — create external issue + if needed, write mapping +- `issue map link|show|detach …` — link existing issue, resolve, detach +- Optional REST `POST/GET /mappings/` if cheap once CLI works; otherwise CLI + first and REST as follow-up task comment + +Does **not** create work records. Creating an external issue without a work +record remains existing `issue create` / `POST /issues/` secondary path. + +**Acceptance:** Documented in README/SCOPE; happy-path test with local +backend; idempotent re-project returns existing mapping. + +## Task: Extend TaskSpec with optional work_record_uuid + +```task +id: ISSUE-WP-0005-T06 +status: todo +priority: medium +``` + +- Add optional `work_record_uuid` (and optional `work_record_id` / + `work_record_kind`) to `TaskIngestionRequest` +- On present UUID: create/reuse issue **and** upsert mapping (T04) +- Without UUID: current behavior (no mapping row) +- Keep `triggering_event_id` semantics unchanged (activity lineage) +- Tests for both paths; update SCOPE TaskSpec section + +**Acceptance:** Backward-compatible OpenAPI/schema; documented; no requirement +that emitters send UUID until ACTIVITY-WP-0022 / intentional project path +uses it. + +## Task: Outward status projection (v1 boundary sync subset) + +```task +id: ISSUE-WP-0005-T07 +status: todo +priority: medium +``` + +Implement **outward-only** application of T03 rules for mapped records +(manual CLI trigger is enough for v1, e.g. `issue map push-status`): + +- Given work-record status input (CLI flag or JSON), update external issue + state per policy table +- Do **not** write work-record files +- Inward sync remains out of scope for this task (document as next) + +**Acceptance:** Policy tests + one integration-style test on local/Gitea mock; +SCOPE distinguishes backend sync vs work-record boundary sync clearly. + +## Task: SCOPE inventory refresh after implementation + +```task +id: ISSUE-WP-0005-T08 +status: todo +priority: medium +``` + +After T04–T07, rewrite SCOPE §1 / §1.8 / §2 so shipped vs target matches +reality (mapping store, CLI, TaskSpec fields, status push). Link T03 policy +doc. Drop stale “design only” claims where implemented. + +**Acceptance:** SCOPE §1 is again the honest inventory; no aspirational +leakage into “shipped today.” + +## Task: Coordinate emitter side (activity-core) without implementing it here + +```task +id: ISSUE-WP-0005-T09 +status: todo +priority: low +``` + +- Confirm ACTIVITY-WP-0022 still covers default sink policy +- If needed, send a state-hub message or progress note linking ISSUE-WP-0005 + mapping readiness to when intentional emits should pass `work_record_uuid` +- Do not implement activity-core changes in this repo + +**Acceptance:** Cross-link noted in this workplan closure notes; no silent +assumption that IssueSink is fixed. + +## Sequencing + +```text +T01 (docs links) ─┬─► T02 (packaging/capability) + └─► T03 (policy doc) ─► T04 (store) ─► T05 (CLI) + └─► T06 (TaskSpec) + └─► T07 (outward status) + └─► T08 (SCOPE refresh) +T09 anytime after T01 (coordination) +``` + +## Acceptance (workplan) + +- [ ] INTENT remains work-record-aligned; review remediation note closed +- [ ] Mapping store + project/link usable on local backend +- [ ] TaskSpec optional UUID path upserts mapping without breaking old clients +- [ ] Dual-lifecycle policy documented and used by outward push +- [ ] SCOPE inventory matches code +- [ ] Packaging/capability/agent docs no longer sell landing-zone coordination +- [ ] activity-core default sink still owned by ACTIVITY-WP-0022 + +## See also + +- `INTENT.md` (2026-07-22 rewrite) +- `SCOPE.md` +- `docs/uuid-external-id-mapping.md` +- `docs/intent-work-record-alignment-review.md` +- `workplans/ISSUE-WP-0004-align-with-work-record-canon.md` +- activity-core `workplans/ACTIVITY-WP-0022-issuesink-no-default-forgejo.md` +- `the-custodian/canon/standards/work-record-types_v0.1.md`