Add comprehensive feedback system that enables lightweight, unstructured feedback collection from users of the issue-facade capability, establishing a continuous improvement loop grounded in real-world usage. Core Components: - .feedback/ directory structure (inbound, reviewed, archived) - Standalone CLI tool (.capability/feedback) for submission and management - Comprehensive documentation (.feedback/README.md) - Integration examples and usage guides Key Features: - Multiple submission methods (CLI, Makefile, direct file drop) - No structure imposement - accepts any text/markdown format - Automatic metadata capture (timestamp, git context, version) - Maintainer workflow (list, review, archive, create issues) - Colored terminal output for better UX - Future-ready for API endpoint evolution Integration: - Updated CAPABILITY.yaml with feedback section - Enhanced CLAUDE.md with comprehensive integration guide - Added Makefile commands (feedback, feedback-list, feedback-stats, etc.) - Created detailed usage examples (examples/feedback-example.md) Design Philosophy: - Capability-agnostic pattern (reusable across all markitect capabilities) - Decentralized (each capability owns its feedback) - Flexible (no required formats or fields) - Durable (plain markdown files, git-tracked) - Actionable (feedback lives where maintainers work) - Scalable (works for 1 user or 1000 users) Feedback Submission Examples: ./.capability/feedback submit "Your feedback" make feedback MSG="Your feedback" echo "Feedback" > .feedback/inbound/$(date +%Y%m%d)-feedback.md Maintainer Workflow: make feedback-list # List pending make feedback-stats # Show statistics make feedback-review-issue FILE=xxx # Review and create issue This establishes a robust continuous improvement loop: User Experience → Feedback → Review → Action → Improved Capability The pattern is designed to be copied to any capability in the markitect project, providing consistent feedback collection across all capabilities. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
16 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Issue Facade is a universal CLI for issue tracking that provides a unified interface to multiple issue tracking backends (GitHub, GitLab, Gitea, local SQLite). It implements the Facade Pattern to abstract away differences between various issue tracking systems, providing developers with a consistent CLI experience regardless of the underlying backend.
Development Commands
Installation & Setup
- Install for development:
pip install -e ".[dev]" - Install production:
pip install -e . - Clean build artifacts:
make issue-facade-clean
Testing
- Run all tests:
pytest tests/ - Run specific test file:
pytest tests/test_gitea_backend.py - Run with coverage:
pytest tests/ --cov=issue_tracker --cov-report=html --cov-report=term - Run integration tests:
pytest tests/test_gitea_integration.py -v
Code Quality
- Run linter:
make issue-facade-lint - Format code:
black issue_tracker/ tests/(line length: 100) - Sort imports:
isort issue_tracker/ tests/
CLI Usage
The project provides two entry points: issue and issue-tracker (both execute issue_tracker.cli.main:main)
Common commands:
issue list- List issuesissue show <number>- Show issue detailsissue create "Title"- Create new issueissue close <number>- Close issueissue backend list- List configured backendsissue sync- Synchronize with remote backend
Architecture
Core Design Pattern: Facade with Plugin Architecture
The codebase implements a plugin-based facade pattern with clear separation of concerns:
┌─────────────────────────────────────────┐
│ CLI Layer (Click) │
│ issue_tracker/cli/*.py │
└───────────────┬─────────────────────────┘
│
┌───────────────▼─────────────────────────┐
│ Core Domain Models │
│ issue_tracker/core/models.py │
│ (Issue, Label, User, etc.) │
└───────────────┬─────────────────────────┘
│
┌───────────────▼─────────────────────────┐
│ Backend Interface (ABC) │
│ issue_tracker/core/interfaces.py │
│ IssueBackend, LocalBackend, │
│ RemoteBackend, SyncableBackend │
└───────────────┬─────────────────────────┘
│
┌───────┴────────┐
│ │
┌───────▼──────┐ ┌──────▼───────┐
│Local Backend │ │Gitea Backend │
│ (SQLite) │ │ (REST API) │
└──────────────┘ └──────────────┘
Key Components
1. Core Domain Models (issue_tracker/core/models.py)
- Issue: Universal issue model with state management, label categorization, and domain logic
- Label: Supports categorization (priority/type/status/other) with cached properties
- User, Milestone, Comment: Supporting models
- IssueState, Priority, IssueType: Enumerations with backend mapping
The Issue model uses @cached_property for performance optimization and includes domain logic methods (close(), reopen(), add_label(), etc.) that enforce business rules.
2. Backend Interface (issue_tracker/core/interfaces.py)
- IssueBackend (ABC): Defines the contract all backends must implement
- LocalBackend, RemoteBackend: Marker interfaces for backend categorization
- SyncableBackend: Interface for backends supporting synchronization
- BackendCapabilities: Describes feature support per backend
- BackendFactory: Registry pattern for backend creation
Critical: All backends MUST implement the full IssueBackend interface. The interface includes:
- Connection management:
connect(),disconnect(),test_connection() - CRUD operations:
create_issue(),get_issue(),update_issue(),delete_issue() - Query operations:
list_issues(),search_issues() - Label, User, Milestone, Comment operations
- Optional:
bulk_update_issues()(if capabilities support it)
3. Backend Implementations
Local Backend (issue_tracker/backends/local/backend.py):
- Uses SQLite with schema defined in
schema.sql - Full offline functionality
- Serves as synchronization source of truth
- Implements
LocalBackendandSyncableBackend
Gitea Backend (issue_tracker/backends/gitea/backend.py):
- REST API integration with Gitea instances
- Rate limiting and error handling
- ID mapping between local and remote issues
- Implements
RemoteBackendandSyncableBackend
4. CLI Layer (issue_tracker/cli/)
- main.py: Entry point, Click group setup, command registration
- commands.py: Core issue operations (list, show, create, close)
- backend_commands.py: Backend management (add, list, switch)
- sync_commands.py: Synchronization operations
- utils.py: Helper functions for formatting and backend access
ID Mapping Strategy
The system uses a dual-ID approach for cross-backend synchronization:
id: Universal ID (UUID for local, external ID for remote)number: Human-readable sequential number (user-facing)backend_id: Backend-specific identifier for sync
When syncing, backends maintain mappings between local numbers and remote IDs. The Gitea backend stores this in sync_metadata on the Issue model.
State Management
IssueState enum provides universal states with backend-specific mapping via to_backend_string():
- OPEN, CLOSED, IN_PROGRESS, BLOCKED
- Some backends (like Gitea) only support OPEN/CLOSED, so IN_PROGRESS and BLOCKED map to OPEN
Testing Strategy
Test Organization
test_gitea_backend.py: Unit tests for Gitea backend with mocked APItest_gitea_integration.py: Full integration tests with real Gitea instancetest_cli_commands.py: CLI command testing
Integration Tests
The integration tests (test_gitea_integration.py) expect a Gitea instance at http://localhost:3000 with test credentials. They create a temporary test repository, run full CRUD operations, and clean up afterwards.
Important: Integration tests use pytest markers:
@pytest.mark.integration- Integration tests (slower)@pytest.mark.unit- Unit tests (fast)
Run only unit tests: pytest -m unit
Run only integration tests: pytest -m integration
Common Development Tasks
Adding a New Backend
- Create backend package in
issue_tracker/backends/<name>/ - Implement
IssueBackendinterface (or extendLocalBackend/RemoteBackend) - Implement all abstract methods from the interface
- Define
BackendCapabilitiesto specify supported features - Register backend in
BackendFactory(typically in__init__.py) - Add configuration handling in CLI backend commands
- Write unit tests with mocked external dependencies
- Write integration tests if applicable
Modifying the Issue Model
When changing issue_tracker/core/models.py:
- Update the
Issuedataclass definition - Update
to_dict()serialization method - Invalidate caches if adding/modifying label-dependent properties
- Update all backend implementations to handle new fields
- Update database schema in
backends/local/schema.sql - Write migration logic if modifying existing fields
Adding CLI Commands
- Add command function in appropriate file (
commands.py,backend_commands.py, etc.) - Use
@click.command()decorator with appropriate options - Call
get_backend(ctx)to retrieve the active backend - Use
format_issue()orformat_issue_list()fromutils.pyfor consistent output - Handle errors with
raise click.ClickException(message) - Register command in
main.pyif creating new command group
Configuration
Project Configuration (pyproject.toml)
- Entry points:
issueandissue-trackercommands - Dependencies: click, requests, python-dateutil
- Optional dependencies: dev, docs, gitea, github, jira
- Code style: Black (line-length=100), isort (profile="black")
- Test markers: unit, integration, slow
Makefile Integration
The capability integrates with the parent markitect project via Makefile:
- Prefixed targets:
issue-facade-*for development commands - Unprefixed targets:
issue-*for user-facing CLI operations - Uses
pip install -efor editable installation
Important Patterns and Conventions
Error Handling
- Backend-specific errors inherit from base exceptions (e.g.,
GiteaAPIError) - CLI commands convert exceptions to
click.ClickExceptionwith user-friendly messages - Use specific exception types for rate limiting, authentication, network issues
Type Hints
- Mypy strict mode enabled (
disallow_untyped_defs = true) - All functions must have type annotations
- Use
Optional[T]for nullable types - Use
List[T],Dict[K, V]fromtypingmodule (Python 3.8 compatibility)
Performance Optimizations
- Use
@cached_propertyfor expensive computations (e.g., label categorization) - Call
invalidate_cache()when modifying cached data - Single-pass algorithms for label categorization in Issue model
Synchronization
When implementing sync:
- Local backend is source of truth
- Remote backends track last sync timestamp
- Use
get_issues_modified_since()for incremental sync - Handle conflicts via
SyncableBackend.resolve_sync_conflict() - Store sync metadata in Issue.sync_metadata dict
Dependencies and External Systems
Runtime Dependencies
- click: CLI framework (>=8.0.0)
- requests: HTTP client for remote backends (>=2.25.0)
- python-dateutil: Date/time parsing (>=2.8.0)
Development Dependencies
- pytest: Testing framework with markers support
- pytest-cov: Coverage reporting
- pytest-mock: Mocking utilities
- black, isort, flake8, mypy: Code quality tools
External Systems
- Gitea API: REST API at
/api/v1/endpoints - SQLite: Local database (no server required)
- Future: GitHub API, GitLab API, JIRA API
Repository Context
This is a capability within the larger markitect project (/capabilities/issue-facade/). The capability:
- Can be installed independently via
pip install -e . - Integrates with parent project via Makefile targets
- Follows markitect capability conventions for structure and naming
Feedback and Continuous Improvement
This capability implements the feedback pattern - a lightweight, unstructured feedback loop for continuous improvement based on real-world usage from master projects integrating this capability.
Overview
The feedback system consists of:
.feedback/directory: Stores all feedback with minimal organization.capability/feedbackCLI tool: Standalone tool for submitting and managing feedback- No structure imposement: Accept any text/markdown format
- Capability-owned: Maintainers organize and prioritize feedback
Directory Structure
.feedback/
├── inbound/ # New feedback from users (unreviewed)
├── reviewed/ # Feedback reviewed by maintainers
├── archived/ # Resolved or outdated feedback
└── README.md # Complete documentation
For Users: Submitting Feedback
Users of issue-facade (master projects integrating it) can submit feedback in multiple ways:
Option 1: Using feedback CLI
# Quick text feedback
./.capability/feedback submit "The sync command is slow with 1000+ issues"
# From a file
./.capability/feedback submit detailed-feedback.md
# With metadata
./.capability/feedback submit "Bug report" --category=bug --contact=me@email.com
Option 2: Direct file drop (no CLI needed)
# Just create a markdown file in inbound/
cat > .feedback/inbound/$(date +%Y%m%d)-sync-issue.md << 'EOF'
The sync is taking 10+ minutes with our 5000-issue repo.
Would love to see progress indicators or batch processing.
EOF
Option 3: From master project
cd my-master-project
echo "Feedback about issue-facade..." > feedback.md
cp feedback.md capabilities/issue-facade/.feedback/inbound/$(date +%Y%m%d)-feedback.md
For Maintainers: Processing Feedback
List and review feedback:
# List pending feedback
./.capability/feedback list
# Show specific feedback
./.capability/feedback show 20251217-103045-abc12345.md
# Show statistics
./.capability/feedback stats
Process feedback:
# Mark as reviewed
./.capability/feedback review 20251217-103045-abc12345.md
# Create issue from feedback
./.capability/feedback review 20251217-103045-abc12345.md --create-issue
# Archive when resolved
./.capability/feedback archive 20251217-103045-abc12345.md
Manual workflow (without CLI):
# 1. List new feedback
ls -lt .feedback/inbound/
# 2. Read feedback
cat .feedback/inbound/20251217-103045-sync-issue.md
# 3. Take action (create issue, fix, document)
issue create "Feature: Show sync progress" \
--description "$(cat .feedback/inbound/20251217-103045-sync-issue.md)" \
--label=feedback --label=feature
# 4. Move to reviewed
mv .feedback/inbound/20251217-103045-sync-issue.md .feedback/reviewed/
Integration with Development Workflow
Feedback informs:
- Roadmap prioritization: Most requested features get priority
- Bug triage: Real-world issues from production usage
- Documentation improvements: Where users struggle
- UX enhancements: Friction points in actual usage
Review rhythm:
- Daily: Quick scan of new feedback
- Weekly: Deep review, create issues, respond to users
- Monthly: Archive old feedback, analyze trends
Feedback Pattern (Reusable Across Capabilities)
The feedback system is capability-agnostic and can be copied to any markitect capability:
-
Copy the pattern:
mkdir -p .feedback/inbound .feedback/reviewed .feedback/archived cp /path/to/feedback-template/README.md .feedback/ cp /path/to/feedback-template/feedback .capability/ chmod +x .capability/feedback -
Document in CAPABILITY.yaml:
feedback: enabled: true method: feedback-capability submission: cli: ".capability/feedback submit 'Your feedback'" directory: ".feedback/inbound/" -
Add to Makefile (optional):
feedback: @./.capability/feedback submit "$(MSG)"
Future Evolution:
- When capability becomes a service, add API endpoint:
POST /api/feedback - API writes to same
.feedback/inbound/directory - Maintains consistency across CLI, file drop, and API submission
Why This Pattern?
- Decentralized: Each capability owns its feedback
- Flexible: No forms, no required structure
- Durable: Plain files survive system changes
- Auditable: Git tracks all feedback
- Actionable: Feedback lives where maintainers work
- Scalable: Works for 1 user or 1000 users
- Future-proof: Can evolve to CLI/API while maintaining structure
See .feedback/README.md for complete documentation.