feat: rename to issue-core and add task ingestion endpoint

Renames the package, distribution, CLI alias, Makefile targets, and
working directory from issue-facade to issue-core, signalling its
role as the authoritative task lifecycle manager for the Coulomb org
(peer to activity-core, rules-core, project-core).

Adds POST /issues/ ingestion endpoint for activity-core's IssueSink,
under a new optional [api] extra. The endpoint is served by `issue
serve`, authenticates via the ISSUE_CORE_API_KEY env var (Bearer or
X-API-Key header), and routes the TaskSpec payload to the configured
default backend with full traceability metadata embedded in
sync_metadata.

- T01: Python package issue_tracker -> issue_core, dir rename
- T02: registered in state hub under custodian domain
- T03: INTENT.md (what it is, what it isn't, how it fits)
- T04: SCOPE.md (in/out-of-scope, integration boundaries)
- T05: POST /issues/ via FastAPI + Uvicorn, 9 unit tests
- T06: docs/nats-task-ingestion.md design stub

Closes ISSC-WP-0001.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-17 05:16:27 +02:00
parent 99ea1fbc45
commit b605d970e3
38 changed files with 1324 additions and 361 deletions

View File

@@ -7,7 +7,7 @@ These tests ensure the Gitea backend works correctly with the API.
import pytest
import json
from unittest.mock import Mock, patch, MagicMock
from issue_tracker.backends.gitea.backend import GiteaBackend, GiteaAPIError
from issue_core.backends.gitea.backend import GiteaBackend, GiteaAPIError
class TestGiteaBackend:
@@ -32,7 +32,7 @@ class TestGiteaBackend:
assert self.backend.repo is None
assert self.backend.session is not None
@patch('issue_tracker.backends.gitea.backend.requests.Session')
@patch('issue_core.backends.gitea.backend.requests.Session')
def test_connect_success(self, mock_session_class):
"""Test successful connection to Gitea API."""
mock_session = MagicMock()
@@ -61,7 +61,7 @@ class TestGiteaBackend:
'Accept': 'application/json'
})
@patch('issue_tracker.backends.gitea.backend.requests.Session')
@patch('issue_core.backends.gitea.backend.requests.Session')
def test_connect_failure(self, mock_session_class):
"""Test failed connection raises appropriate error."""
mock_session = MagicMock()
@@ -96,7 +96,7 @@ class TestGiteaBackend:
called_url = mock_request.call_args[1]['url'] if 'url' in mock_request.call_args[1] else mock_request.call_args[0][1]
assert called_url == 'https://git.example.com/api/v1/repos/owner/repo'
@patch('issue_tracker.backends.gitea.backend.requests.Session')
@patch('issue_core.backends.gitea.backend.requests.Session')
def test_test_connection_success(self, mock_session_class):
"""Test test_connection method works correctly."""
mock_session = MagicMock()
@@ -117,7 +117,7 @@ class TestGiteaBackend:
result = backend.test_connection()
assert result is True
@patch('issue_tracker.backends.gitea.backend.requests.Session')
@patch('issue_core.backends.gitea.backend.requests.Session')
def test_test_connection_failure(self, mock_session_class):
"""Test test_connection handles failures gracefully."""
mock_session = MagicMock()
@@ -139,7 +139,7 @@ class TestGiteaBackend:
result = backend.test_connection()
assert result is False
@patch('issue_tracker.backends.gitea.backend.requests.Session')
@patch('issue_core.backends.gitea.backend.requests.Session')
def test_get_issue_success(self, mock_session_class):
"""Test successful issue retrieval."""
mock_session = MagicMock()