Files
issue-core/workplans/ISSC-WP-0001-rename-and-task-ingestion.md
tegwick 663d1961cf chore(workplan): stub ISSC-WP-0001 rename to issue-core and task ingestion
Workplan for renaming issue-facade → issue-core and implementing the
POST /issues/ task ingestion endpoint required by activity-core's IssueSink
adapter. Covers rename, state hub registration, INTENT.md, SCOPE.md, REST
endpoint, and NATS design stub.

Hub workstream: 1135fc1d-1f46-4e35-886d-04cc3b8050b6

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 18:12:38 +02:00

8.2 KiB

id, type, domain, repo, status, state_hub_workstream_id, tasks, created
id type domain repo status state_hub_workstream_id tasks created
ISSC-WP-0001 workplan custodian issue-facade active 1135fc1d-1f46-4e35-886d-04cc3b8050b6
id title state_hub_task_id status
T01 Rename package issue-facade → issue-core throughout b7054428-82a9-4d81-bfa8-5b5ee2eaf69f todo
id title state_hub_task_id status
T02 Register issue-core in state hub under capabilities domain b1d36996-44ff-48b9-b208-709d6874453c todo
id title state_hub_task_id status
T03 Write INTENT.md 265c6338-0310-409d-a081-6446042f6274 todo
id title state_hub_task_id status
T04 Update or write SCOPE.md f95ac730-7ba0-4eae-bcae-de1e7d24b164 todo
id title state_hub_task_id status
T05 Implement task ingestion REST endpoint POST /issues/ 26af07e4-c072-42ad-bb5c-facb196156c9 todo
id title state_hub_task_id status
T06 Document NATS subscriber interface (design stub) dff61fed-1e8c-4eb3-bbd6-1e3742329945 todo
2026-05-14

ISSC-WP-0001: Rename to issue-core and Task Ingestion

Purpose

Two things need to happen to make issue-facade a proper peer to activity-core in the Coulomb org architecture:

  1. Rename: issue-facade is a misleading name — it is not a facade, it is the authoritative task lifecycle manager for the org. Renaming to issue-core aligns with the naming pattern (activity-core, rules-core, project-core) and signals its role clearly.

  2. Task ingestion endpoint: activity-core's IssueSink adapter emits tasks to issue-core via REST. That endpoint must exist, be stable, and accept TaskSpec payloads from activity-core. Without it, activity-core's task emission is a no-op.

Context

  • activity-core WP-0003 (in progress): implements IssueSinkAdapter in src/activity_core/issue_sink.py. It calls POST /issues/ on issue-core to create tasks from ActivityDefinition rule/instruction output.
  • issue-facade currently: multi-backend task tracker (Gitea, SQLite, GitHub). Handles task creation and tracking. Has no incoming task-ingestion API from external callers like activity-core.
  • State hub gap: issue-facade is not registered in the Custodian State Hub. This makes cross-repo workstream tracking impossible.

See: docs/adr/adr-001-event-bridge-architecture.md in activity-core for the IssueSink adapter design and the task emission flow.

Scope

In scope:

  • Package rename (issue-facade → issue-core)
  • State hub registration
  • INTENT.md and SCOPE.md
  • Task ingestion REST endpoint (POST /issues/)
  • NATS subscriber interface design stub

Out of scope:

  • Project management features (that is project-core, future)
  • UI or end-user facing changes
  • Changing backends (Gitea/SQLite/GitHub adapters stay as-is)

TaskSpec Payload (from activity-core)

The POST /issues/ endpoint receives this payload from activity-core's IssueSink:

{
  "title": "string",
  "description": "string",
  "target_repo": "string",
  "priority": "high | medium | low",
  "labels": ["string"],
  "due_in_days": 7,
  "source_type": "rule | instruction",
  "source_id": "string",
  "triggering_event_id": "uuid",
  "activity_definition_id": "string"
}

The endpoint must return:

{
  "issue_id": "string",
  "issue_url": "string or null",
  "backend": "gitea | sqlite | github"
}

The issue_id is stored in activity-core's task_spawn_log as the external reference. It is not managed by activity-core — it belongs to issue-core.

Tasks

T01 — Rename package issue-facade → issue-core throughout

Rename everywhere:

  • pyproject.toml: name = "issue-core", update entry points
  • Python package directory: issue_facade/issue_core/ (if applicable)
  • All import issue_facadeimport issue_core
  • CLI command names if changed
  • README, CHANGELOG headers
  • Docker Compose service names and image tags
  • Any Makefile targets

After renaming, run the full test suite to confirm no broken imports. Update the workplans/ frontmatter repo: issue-core once renamed.

T02 — Register issue-core in state hub under capabilities domain

Call register_repo() on the state hub MCP:

register_repo(slug="issue-core", path="/home/worsch/issue-facade",
              domain="custodian")  # or capabilities if domain exists

Note: the directory may still be named issue-facade — register with slug="issue-core" and update path once the rename is complete.

T03 — Write INTENT.md

Write INTENT.md explaining:

  • Why it exists: the Coulomb org needs a single, observable place where tasks land — regardless of whether they were created by a human, by activity-core, or by an agent.
  • What it is: task lifecycle manager (create, assign, update, close) with pluggable backends (Gitea, SQLite, GitHub).
  • What it is NOT: not a project manager (no phases, no campaigns, no dependency graphs — that is project-core). Not a spawn audit trail (that is activity-core). Not an event bus.
  • How it fits: activity-core emits tasks here via IssueSink; humans and agents consume them; status updates flow back to issue-core (not to activity-core).

T04 — Update or write SCOPE.md

Check if SCOPE.md exists. If yes, update:

  • Rename references (issue-facade → issue-core)
  • Add activity-core as an upstream emitter via IssueSink REST
  • Add "Out of scope" section if missing: project management, spawn audit trail
  • Update "How it fits" to reference activity-core architecture

If no SCOPE.md exists, write one from scratch following the standard format.

T05 — Implement task ingestion REST endpoint POST /issues/

Implement POST /issues/ (or POST /tasks/create — check existing naming convention and pick the most consistent path):

@router.post("/issues/")
async def ingest_task(payload: TaskIngestionRequest) -> TaskIngestionResponse:
    ...

The endpoint must:

  1. Validate the payload against TaskIngestionRequest schema
  2. Route to the correct backend based on target_repo (look up backend config)
  3. Create the issue/task in the backend
  4. Return {issue_id, issue_url, backend}
  5. Log the ingestion with triggering_event_id for traceability

Key file: issue_core/api/ingest.py (new) or alongside existing API routes.

Security: the endpoint should require an API key header (check existing auth pattern in the codebase). Do not expose it unauthenticated.

T06 — Document NATS subscriber interface (design stub)

Design stub only — implementation deferred until activity-core's IssueSink migrates from REST to NATS.

Document in docs/nats-task-ingestion.md:

  • Proposed NATS subject pattern: act.tasks.create.{target_repo}
  • Message schema (same TaskIngestionRequest as REST endpoint)
  • Consumer group config: durable consumer, at-least-once delivery
  • Idempotency key: triggering_event_id — used to deduplicate retries

Build Order

T01 (rename) → T02 (register) → T03 (INTENT.md) → T04 (SCOPE.md)
T01 (rename) → T05 (REST endpoint) → T06 (NATS stub, depends on endpoint schema)

Completion Criteria

  1. Package renamed to issue-core; all tests pass after rename
  2. issue-core registered in state hub
  3. INTENT.md and SCOPE.md committed and accurate
  4. POST /issues/ endpoint implemented and tested with a TaskSpec payload
  5. activity-core agent confirmed IssueSink integration works end-to-end
  6. NATS design stub committed to docs/

Notes

  • Directory name: if renaming the repository directory (issue-facade/issue-core/) — coordinate with Bernd first, as it will invalidate any relative paths or symlinks.
  • T01 first: all other tasks depend on the rename being settled. The directory path in state hub registration (T02) must reflect the final name.
  • Backwards compat: if external consumers call the existing API using paths under issue-facade, add redirect aliases rather than breaking them.
  • The NATS stub (T06) should be implemented as a comment-heavy skeleton so the activity-core agent can wire the NATS IssueSink without waiting for a full implementation.

Change History

  • v0.1 (2026-05-14): Stub created by activity-core agent during WP-0003 planning. Local agent to flesh out and implement.