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

@@ -50,7 +50,7 @@ A **Capability Family** is an abstract, conceptual grouping of related functiona
A **Capability Implementation** is a concrete realization of a Capability Family - the actual code, tools, and patterns that provide the functionality.
**Examples:**
- `issue-facade` - An implementation of the `issue-tracking` family
- `issue-core` - An implementation of the `issue-tracking` family
- `feedback-tool` - An implementation of the `feedback-collection` family
**Characteristics:**
@@ -94,7 +94,7 @@ CAPABILITY-authentication.yaml # Declares authentication capability
### Single Capability Repository Structure
```
issue-facade/ # Repository name (implementation)
issue-core/ # Repository name (implementation)
├── CAPABILITY-issue-tracking.yaml # Declares: provides "issue-tracking"
├── README.md # Human-readable documentation
├── feedback/ # Visible: user interface for feedback
@@ -105,7 +105,7 @@ issue-facade/ # Repository name (implementation)
│ ├── feedback # Feedback CLI tool
│ ├── integrate.sh # Integration script
│ └── ...
├── issue_tracker/ # Core implementation code
├── issue_core/ # Core implementation code
│ ├── core/
│ ├── backends/
│ └── cli/
@@ -141,7 +141,7 @@ unified-devtools/ # Repository providing multiple capab
│ ├── feedback-collection/
│ └── common/
├── src/
│ ├── issue_tracker/
│ ├── issue_core/
│ ├── feedback_tool/
│ └── doc_generator/
└── tests/
@@ -162,8 +162,8 @@ Traditional approaches create deep directory trees:
```
my-project/
└── capabilities/
└── issue-facade/
└── issue_tracker/
└── issue-core/
└── issue_core/
└── backends/
└── gitea/
└── backend.py # 6 levels deep!
@@ -176,8 +176,8 @@ Use **underscore-prefixed directories** at the repository root to signal "integr
**Option A: Implementation-Based (Recommended)**
```
my-project/
├── _issue-facade/ # Integrated capability (flat!)
│ └── issue_tracker/ # Only 2-3 levels deep
├── _issue-core/ # Integrated capability (flat!)
│ └── issue_core/ # Only 2-3 levels deep
│ └── backends/
├── _feedback-tool/ # Another integrated capability
├── src/ # Core project code
@@ -190,7 +190,7 @@ my-project/
```
my-project/
├── _issue-tracking/ # Capability family
│ └── issue-facade/ # Implementation (if multiple needed)
│ └── issue-core/ # Implementation (if multiple needed)
├── _feedback-collection/
│ └── feedback-tool/
└── src/
@@ -200,7 +200,7 @@ my-project/
```
my-project/
├── c/ # "c" for capabilities
│ ├── issue-facade/
│ ├── issue-core/
│ └── feedback-tool/
└── src/
```
@@ -208,7 +208,7 @@ my-project/
**Recommendation: Option A (Implementation-Based)**
**Rationale:**
- **Flatter hierarchy** - `_issue-facade/issue_tracker/...` (3 levels vs 6)
- **Flatter hierarchy** - `_issue-core/issue_core/...` (3 levels vs 6)
- **Clear signal** - underscore means "integrated, not core"
- **Discoverable** - `ls _*/` shows all integrated capabilities
- **No ambiguity** - implementation name is explicit
@@ -217,7 +217,7 @@ my-project/
**Example:**
```
my-project/
├── _issue-facade/ # Issue tracking via issue-facade
├── _issue-core/ # Issue tracking via issue-core
├── _auth-service/ # Authentication via auth-service
├── _postgres-tools/ # Database tools
├── src/ # Core project code
@@ -236,11 +236,11 @@ my-project/
ls -d _*/
# Read capability specs
cat _issue-facade/CAPABILITY-*.yaml
cat _issue-core/CAPABILITY-*.yaml
cat _auth-service/CAPABILITY-*.yaml
```
**Important:** The underscore prefix is **local convention** for integrated capabilities, not part of the upstream git repository name. When integrating `github.com/markitect/issue-facade`, it becomes `_issue-facade/` in your project.
**Important:** The underscore prefix is **local convention** for integrated capabilities, not part of the upstream git repository name. When integrating `github.com/markitect/issue-core`, it becomes `_issue-core/` in your project.
---
@@ -252,7 +252,7 @@ cat _auth-service/CAPABILITY-*.yaml
# CAPABILITY-issue-tracking.yaml
metadata:
family: issue-tracking
implementation: issue-facade
implementation: issue-core
version: 1.0.0
description: >
Unified interface for issue tracking across Gitea, GitHub, GitLab.
@@ -276,7 +276,7 @@ integration:
mcp_server: false # planned
installation:
command: "pip install -e _issue-facade/"
command: "pip install -e _issue-core/"
verify: "issue --version"
documentation:
@@ -295,7 +295,7 @@ feedback:
# CAPABILITY-issue-tracking.yaml
metadata:
family: issue-tracking
implementation: issue-facade
implementation: issue-core
version: 1.0.0
maturity: production # experimental, beta, production
@@ -338,7 +338,7 @@ integration:
methods:
python_api:
available: true
import: "from issue_tracker.backends.gitea import GiteaBackend"
import: "from issue_core.backends.gitea import GiteaBackend"
docs: "AGENT_INTEGRATION.md"
cli:
@@ -354,7 +354,7 @@ integration:
installation:
method: pip
command: "pip install -e _issue-facade/"
command: "pip install -e _issue-core/"
verify: "issue --version"
configuration:
@@ -421,8 +421,8 @@ credentials:
security:
- "Tokens never in code or logs"
- "Config stored in ~/.config/issue-facade/"
- "Per-repo config in .issue-facade/ (gitignored)"
- "Config stored in ~/.config/issue-core/"
- "Per-repo config in .issue-core/ (gitignored)"
# Documentation references
documentation:
@@ -504,13 +504,13 @@ cat feedback/README.md
**Integrate a capability:**
```bash
# Clone/copy into underscore-prefixed directory
git clone https://github.com/markitect/issue-facade _issue-facade
git clone https://github.com/markitect/issue-core _issue-core
# Or use git submodule
git submodule add https://github.com/markitect/issue-facade _issue-facade
git submodule add https://github.com/markitect/issue-core _issue-core
# Install
pip install -e _issue-facade/
pip install -e _issue-core/
# Verify
issue --version
@@ -546,18 +546,18 @@ def find_capability_family(repo_path, family_name):
return None
# Usage
capabilities = discover_capabilities("_issue-facade")
capabilities = discover_capabilities("_issue-core")
# Returns: [{'metadata': {'family': 'issue-tracking', ...}}]
issue_cap = find_capability_family("_issue-facade", "issue-tracking")
issue_cap = find_capability_family("_issue-core", "issue-tracking")
print(f"Found: {issue_cap['metadata']['implementation']}")
# Output: Found: issue-facade
# Output: Found: issue-core
```
**Use capability via natural language understanding:**
```python
# Agent reads capability spec
spec = find_capability_family("_issue-facade", "issue-tracking")
spec = find_capability_family("_issue-core", "issue-tracking")
# Agent understands use-cases
use_cases = spec['purpose']['use_cases']
@@ -566,7 +566,7 @@ use_cases = spec['purpose']['use_cases']
# Agent discovers integration methods
if spec['integration']['methods']['python_api']['available']:
import_statement = spec['integration']['methods']['python_api']['import']
# "from issue_tracker.backends.gitea import GiteaBackend"
# "from issue_core.backends.gitea import GiteaBackend"
# Agent can now integrate programmatically
exec(import_statement)
@@ -616,7 +616,7 @@ metadata:
# This capability integrates other capabilities
integrates:
- family: issue-tracking
implementation: issue-facade
implementation: issue-core
version: ">=1.0.0"
reason: "Uses issue tracking for task management"
@@ -635,12 +635,12 @@ integrates:
```
pm-tool/
├── CAPABILITY-project-management.yaml
├── _issue-facade/ # Integrated capability
├── _issue-core/ # Integrated capability
├── _feedback-tool/ # Integrated capability
├── _doc-gen/ # Integrated capability
├── src/
│ └── pm/
│ ├── tasks.py # Uses issue-facade
│ ├── tasks.py # Uses issue-core
│ ├── feedback.py # Uses feedback-tool
│ └── docs.py # Uses doc-gen
└── README.md
@@ -660,7 +660,7 @@ integrates:
**Multiple valid integrations:**
```
pm-tool/
├── _issue-facade/ # Option 1: issue-facade implementation
├── _issue-core/ # Option 1: issue-core implementation
└── ...
pm-tool/
@@ -740,7 +740,7 @@ Project C needs Gitea issues
→ Pattern: "We need issue tracking"
→ Family: "issue-tracking"
→ Implementation 1: issue-facade (multi-backend)
→ Implementation 1: issue-core (multi-backend)
→ Implementation 2: github-native (GitHub-only, optimized)
→ Implementation 3: jira-bridge (JIRA connector)
@@ -757,7 +757,7 @@ All implement "issue-tracking" family with different trade-offs
**Implementation Versions:**
- Implementations evolve independently
- Follow semantic versioning (semver)
- Example: `issue-facade@1.2.3`, `github-native@0.5.0`
- Example: `issue-core@1.2.3`, `github-native@0.5.0`
**Compatibility:**
```yaml
@@ -765,7 +765,7 @@ All implement "issue-tracking" family with different trade-offs
metadata:
family: issue-tracking
family_version: "1.x" # Compatible with v1 family spec
implementation: issue-facade
implementation: issue-core
version: 1.2.3 # Implementation version
```
@@ -785,9 +785,9 @@ metadata:
### For Capability Users (Integrators)
1. **Prefer Families over Implementations** - Depend on `issue-tracking`, not `issue-facade`
1. **Prefer Families over Implementations** - Depend on `issue-tracking`, not `issue-core`
2. **Pin Versions Loosely** - `>=1.0.0, <2.0.0` allows updates
3. **Use Underscore Prefix** - `_issue-facade/` signals "integrated"
3. **Use Underscore Prefix** - `_issue-core/` signals "integrated"
4. **Provide Feedback** - Use `feedback/` to guide improvement
5. **Read the Spec** - `CAPABILITY-*.yaml` is the contract
6. **Check Maturity** - Match capability maturity to your needs
@@ -846,7 +846,7 @@ git commit -m "refactor: align with ReusableCapabilitiesArchitecture v0.1"
**Solution:** Underscore signals "used by this repo, not core to it"
**Benefits:**
- Visual distinction: `_issue-facade/` vs `src/`
- Visual distinction: `_issue-core/` vs `src/`
- Flatter hierarchy: 2-3 levels vs 5-6 levels
- Easy discovery: `ls _*/` lists all integrations
- Works with tab completion: `cd _<tab>` shows capabilities
@@ -877,8 +877,8 @@ multi-backend-tool/
├── CAPABILITY-issue-tracking-v1.yaml # Stable, production backend
├── CAPABILITY-issue-tracking-v2.yaml # Experimental, next-gen backend
├── src/
│ ├── v1/ # issue-facade-classic
│ └── v2/ # issue-facade-next
│ ├── v1/ # issue-core-classic
│ └── v2/ # issue-core-next
└── README.md
```
@@ -896,10 +896,10 @@ Agents consider:
```python
# Agent logic
capabilities = discover_capabilities(".")
issue_trackers = [c for c in capabilities if c['metadata']['family'] == 'issue-tracking']
issue_cores = [c for c in capabilities if c['metadata']['family'] == 'issue-tracking']
# Filter by maturity
production_ready = [c for c in issue_trackers if c['metadata']['maturity'] == 'production']
production_ready = [c for c in issue_cores if c['metadata']['maturity'] == 'production']
# Choose highest version
best = max(production_ready, key=lambda c: c['metadata']['version'])
@@ -986,13 +986,13 @@ devtools-suite/
```
my-saas-app/
├── _issue-facade/ # Issue tracking capability
├── _issue-core/ # Issue tracking capability
├── _auth-service/ # Authentication capability
├── _feedback-tool/ # Feedback collection capability
├── src/
│ └── myapp/
│ ├── api/
│ │ ├── issues.py # Uses _issue-facade
│ │ ├── issues.py # Uses _issue-core
│ │ └── auth.py # Uses _auth-service
│ ├── models/
│ └── main.py
@@ -1004,15 +1004,15 @@ my-saas-app/
**Installation:**
```bash
# Clone integrated capabilities
git submodule add https://github.com/markitect/issue-facade _issue-facade
git submodule add https://github.com/markitect/issue-core _issue-core
git submodule add https://github.com/markitect/auth-service _auth-service
git submodule add https://github.com/markitect/feedback-tool _feedback-tool
# Install
pip install -e _issue-facade/ -e _auth-service/ -e _feedback-tool/
pip install -e _issue-core/ -e _auth-service/ -e _feedback-tool/
# Use in code
from issue_tracker.backends.gitea import GiteaBackend
from issue_core.backends.gitea import GiteaBackend
from auth_service import AuthManager
```