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>
This commit is contained in:
2026-05-14 18:12:38 +02:00
parent 70d7ec0cdc
commit 663d1961cf

View File

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