71 lines
2.2 KiB
Markdown
71 lines
2.2 KiB
Markdown
|
|
# Boundary sync and status mapping (v1)
|
||
|
|
|
||
|
|
**Status:** normative for ISSUE-WP-0005
|
||
|
|
**Date:** 2026-07-22
|
||
|
|
**Implements:** INTENT “Boundary sync discipline”
|
||
|
|
**Related:** `docs/uuid-external-id-mapping.md`, `issue_core/core/mapping.py`
|
||
|
|
|
||
|
|
## Principles
|
||
|
|
|
||
|
|
1. Fleet **work-record `status`** and tracker **`IssueState`** are distinct
|
||
|
|
vocabularies. Never treat them as the same enum.
|
||
|
|
2. **v1 is outward-only.** Operators (or automation) call
|
||
|
|
`issue map push-status` with a work-record status; issue-core updates the
|
||
|
|
external issue. Inward sync does **not** write work-record files.
|
||
|
|
3. **Lane, tags, budgets** stay on the work record. Projections may carry
|
||
|
|
title, body, and agreed labels only.
|
||
|
|
4. Unmapped backend issues are **outside** the work-record spine.
|
||
|
|
|
||
|
|
## Mapping keys
|
||
|
|
|
||
|
|
| Side | Key |
|
||
|
|
| --- | --- |
|
||
|
|
| Work record | **UUIDv7** (bookkeeping); canonical id optional denorm for UX |
|
||
|
|
| External | `(backend, external_id)` where backend is `sqlite` \| `gitea` \| … |
|
||
|
|
|
||
|
|
## Outward status table (task kind + pass-through)
|
||
|
|
|
||
|
|
| Work-record / input status | Tracker `IssueState` |
|
||
|
|
| --- | --- |
|
||
|
|
| `wait` | `open` |
|
||
|
|
| `todo` | `open` |
|
||
|
|
| `progress` | `in_progress` |
|
||
|
|
| `done` | `closed` |
|
||
|
|
| `cancel` | `closed` |
|
||
|
|
| `open` | `open` (pass-through) |
|
||
|
|
| `in_progress` | `in_progress` |
|
||
|
|
| `blocked` | `blocked` |
|
||
|
|
| `closed` | `closed` |
|
||
|
|
|
||
|
|
Other kinds (intake, decision, …) should not use this table until kind-
|
||
|
|
specific rules are added. Prefer projecting only after promotion to `task`
|
||
|
|
when unsure.
|
||
|
|
|
||
|
|
## Fields
|
||
|
|
|
||
|
|
| May project outward | Stay on work record only |
|
||
|
|
| --- | --- |
|
||
|
|
| title, description/body | `lane` |
|
||
|
|
| labels agreed for external collab | policy/derived `tags` |
|
||
|
|
| tracker state (via table above) | budgets / token envelopes |
|
||
|
|
| comments (future) | owner spine identity (`agt-…`) |
|
||
|
|
|
||
|
|
## CLI
|
||
|
|
|
||
|
|
```bash
|
||
|
|
issue map push-status --uuid <work-record-uuid> --status progress
|
||
|
|
issue map push-status --id ISSUE-WP-0005-T07 --status done
|
||
|
|
```
|
||
|
|
|
||
|
|
## Non-goals (v1)
|
||
|
|
|
||
|
|
- Silent mutation of ADR-001 work-record files from tracker webhooks
|
||
|
|
- Full comment CRDT merge
|
||
|
|
- Multi-backend active mappings per UUID (one active per backend)
|
||
|
|
|
||
|
|
## Implementation
|
||
|
|
|
||
|
|
- Policy function: `map_work_record_status_to_issue_state()` in
|
||
|
|
`issue_core/core/mapping.py`
|
||
|
|
- CLI: `issue map push-status`
|