# INTENT.md vs work-record framework — alignment review **Date:** 2026-07-21 **Subject:** `INTENT.md` (issue-core) **Compared to:** | Source | Role | | --- | --- | | `the-custodian/canon/standards/work-record-types_v0.1.md` | Ratified work-record types & identity (v0.1, CUST-WP-0060) | | `the-custodian/research/WorkOrchestrationArchitectureDraft.md` v0.2 §4.2, §1, §8 | Founder-reviewed architecture (connector decision) | | `the-custodian/canon/architecture/adr-001-workplans-as-repo-artefacts.md` | File-first origin of work items | | `SCOPE.md` (post-2026-07-21 inventory rewrite) | What this repo actually ships | | `docs/uuid-external-id-mapping.md` | Mapping design (not implemented) | **Method:** Line-level reading of INTENT against the closed kind registry, identity layering, reconciliation loop, and §4.2 connector decision. Classify each topic as **aligned**, **soft friction**, **hard collision**, or **gap** (framework has it; INTENT is silent in a way that can mislead). **Verdict (one line):** INTENT is **strategically aligned** with the work-record restructuring (connector, not origin / not core loop). Remaining problems are **terminology precision**, **diagram topology**, **dual lifecycle silence**, and **aspirational “What it is” vs shipped reality** — not a return to the landing-zone role. --- ## 1. Work-record framework (compressed) The fleet restructured coordination around one umbrella and one loop: 1. **Work record** = any identified, lifecycle-bearing coordination artefact. 2. **Closed kinds:** `workplan`, `task`, `intake`, `decision`, `engagement`, `register-entry` — each with id scheme + abstract lifecycle. 3. **Spine fields:** `id`, `uuid` (UUIDv7), `kind`, `lane`, `status`, `owner`, `repo`, `tags`, `created`/`updated`. 4. **Identity layering:** UUIDv7 for bookkeeping; **canonical names** for humans/agents; hub writes UUID back into the source file. 5. **Origin:** any repo file may host schema-valid records (ADR-001 extended); hub is a **read model**; `fix-consistency` registers and write-backs. 6. **Views** are generated (`[auto]`); hand queues are retired. 7. **Promotion** is first-class: `intake.routed → workplan|task|decision|engagement`. 8. **issue-core** (architecture §4.2, kind table absorbs column): *connector to third-party trackers; mapping UUID ↔ external issue id; two-way boundary sync; not part of the internal execution loop; zero load until an integration is switched on.* Task-kind legacy note: *“issue-core issues become external projections only.”* --- ## 2. Alignment matrix | Framework claim | INTENT stance | Rating | | --- | --- | --- | | Work originates as repo files (ADR-001) | Explicit in “Why”, “What it is NOT”, primary path | **Aligned** | | Hub is read model / index | Primary path + diagram (hub as read model) | **Aligned** (diagram caveat in §3.2) | | issue-core is connector, not core loop | Title framing, §4.2 quote in history, NOT list | **Aligned** | | Mapping UUID ↔ external issue id | Stated as target responsibility + design link | **Aligned** (not shipped — see §4) | | Two-way boundary sync when tracker on | Listed under “What it is” | **Soft friction** (sounds present; is target) | | Zero load until integration on | Explicit success criterion | **Aligned** | | Issues are not a work-record kind | No inventing an `issue` kind; “external projections” | **Aligned** | | Task lifecycle is `wait/todo/progress/done\|cancel` | Silent; IssueState is separate universe | **Soft friction / gap** | | Closed kind list (6 kinds) | Mentions workplan / task / intake only | **Soft friction** (incomplete, not wrong) | | UUIDv7 + canonical name dual identity | “UUIDs” only | **Soft friction** | | Lanes, tags, budgets on every work record | Silent | **Gap** (acceptable for connector INTENT if projection never re-encodes them) | | Promotion (`intake → …`) as proper path for findings | Says “don’t IssueSink”; does not name intake | **Gap** | | Reconciliation loop (file → CI → fix-consistency → views → NATS) | issue-core kept off-loop (correct) | **Aligned** | | Direct CLI/REST without work-record birth | Secondary path allowed for tracker admin | **Aligned with caveat** (§3.4) | | activity-core must not default-spam Forgejo | Explicit secondary-path note + WP follow-up | **Aligned** (operational debt remains outside INTENT) | No **hard collision** found: INTENT does not reassert “single landing zone” as the product north star, does not claim issue-core authors workplans/tasks as fleet origin, and does not place Forgejo inside the internal claim/execute loop. --- ## 3. Soft frictions and near-collisions ### 3.1 Identity: UUID-only vs two-layer identity **Framework:** UUIDv7 is primary for bookkeeping; **canonical names** (`ISSUE-WP-0004-T01`, …) are primary for humans and agents. **INTENT:** Speaks of “work-record identity (UUIDs)” and “UUID ↔ issue id” without naming UUIDv7 or the human-facing id. **Why it matters:** Mapping implementation and CLI (`issue project ISSUE-WP-…`) will almost always start from the **canonical name**; storage key should be UUID. INTENT’s UUID-only phrasing can steer readers to hide canonical ids or treat Gitea numbers as peer identity to human task names. **Recommendation:** In INTENT “Why / Mapping”, say: > Mapping keys on work-record **UUIDv7** (bookkeeping); operators and agents > still address records by **canonical id**; external side is > `(backend, external_id)`. ### 3.2 Diagram topology: hub as mapping peer INTENT diagram: ```text state-hub <---- mapping ------> issue-core ``` **Framework topology is closer to:** ```text repo file (work record) --index--> state-hub (read model / views) | | optional project v issue-core (mapping store + backends) --> Forgejo/GitHub/… ``` **Friction:** Drawing hub ↔ issue-core as the mapping edge suggests the hub is the internal endpoint of the connector. Canon: the **source file** (plus optional denorm back-reference) is authoritative; the hub indexes it. Mapping authority lives in issue-core’s store (design) and optionally write-back fields on the work-record file — not “hub owns the mapping.” **Recommendation:** Redraw so work-record **files** are the left box; hub is an index/view layer; mapping sits on issue-core ↔ file (and/or issue-core store). ### 3.3 Dual lifecycles (silent dualism) | Layer | Status vocabulary | | --- | --- | | Work-record **task** | `wait → todo → progress → done \| cancel` | | Work-record **intake** | `open → vetted → routed → closed(…)` | | issue-core `IssueState` | `open`, `closed`, `in_progress`, `blocked` | **INTENT** correctly says issue-core is not the execution loop, but never warns that **these state machines are not the same thing** and must not be merged casually during boundary sync. **Risk:** Future “two-way sync” implementers map `progress ↔ in_progress` loosely and write fleet status from Forgejo (or vice versa) without a defined writer — colliding with ADR-001 file authority and flow profiles. **Recommendation:** One short “Boundary sync discipline” bullet under NOT / How it fits: > Fleet `status` and tracker `IssueState` are distinct. Sync is explicit > projection rules, never silent mutation of work-record files without a > defined writer (see mapping design). ### 3.4 Secondary path: tracker issues outside the spine INTENT allows direct `$ issue create` / intentional REST **without** creating a work-record origin — correct for pure external collaboration. **Caveat vs framework:** Anything that is *fleet coordination work* must still be a work record. Unmapped tracker issues are **external artefacts**, not second-class work records. INTENT’s “without creating a work-record origin” is right; it should not be read as “tracker issues are informal work records.” **Recommendation:** One clarifying sentence: > Unmapped backend issues are outside the work-record spine. They become > fleet-visible only when mapped to a work-record UUID (or when humans look > at the tracker UI for external collab only). ### 3.5 Incomplete kind list INTENT diagram: `workplan / task / intake / …` Framework closed list also includes **decision**, **engagement**, **register-entry**. Not a collision — ellipsis is honest — but projection design should not assume “only tasks project.” Engagements (counterparty-facing) and some register entries may also need external issues. Mapping design already allows `work_record_kind`; INTENT could point at the full registry once. ### 3.6 “Intake” overloaded INTENT: “harness intake via NATS/activity-core.” Framework: **`intake` is a work-record kind**. Readers can conflate “event/task intake path” with “`kind: intake` spark items.” Soft terminology debt shared with the architecture draft’s own wording (“harness intake”). **Recommendation:** Prefer “harness **claim/execute** on work records (NATS/activity-core as feed)” and reserve **intake** for the kind when possible. ### 3.7 Promotion gap (findings path incomplete) Framework answer to “automation found something”: ```text finding → kind:intake (repo file) → promote → task|workplan|… optional later: issue-core project → external tracker ``` INTENT answer: ```text finding ↛ IssueSink/Forgejo (good) finding → ??? (unspecified) ``` Not a collision with architecture §4.2, but **incomplete operational intent** after the landing-zone ban. Operators reading only INTENT may pause sinks and have no named replacement. **Recommendation:** Point at intake kind + promotion as the fleet path; reference ACTIVITY-WP-0022 for sink policy and CUST-WP-0060 follow-ups. ### 3.8 Lanes / tags / budgets Framework makes `lane` mandatory on every work record; tags and budgets are normative. INTENT is silent — **acceptable** if projections never invent parallel lane/budget models on issues. Soft risk if Gitea labels start carrying a second autonomy model (`lane:green` as issue labels without mapping rules). **Recommendation:** Mapping/projection: lane, tags, budget stay on the work record; tracker gets only fields needed for external collab (title, body, labels agreed for humans). --- ## 4. Aspirational INTENT vs shipped reality INTENT’s “What it is” lists responsibilities that mix **shipped** and **target**. Cross-check with SCOPE inventory: | Responsibility in INTENT | Shipped? | | --- | --- | | Projection / CRUD on backends | **Yes** (SQLite, Gitea) | | Mapping UUID ↔ external id | **No** — design only | | Two-way boundary sync | **No** — CLI backend sync ≠ work-record boundary sync | | CLI + REST | **Yes** | | Optional intentional ingestion | **Yes** (and still over-used operationally) | | Zero load when off | **Partially** — process can still run; product rule is policy + idle mapping, not auto-enforced | **Friction with framework:** Architecture §4.2 presents mapping + boundary sync as *the* connector role. INTENT correctly marks mapping as target in one bullet but lists boundary sync without the same “target” qualifier. Readers can believe the work-record-aware connector is done when only the pre-canon CRUD shell exists. **Recommendation:** Split INTENT “What it is” into **Shipped today** vs **Target connector (stage-3)**, mirroring SCOPE §1 vs §2. --- ## 5. Hard collisions **None** between INTENT’s product north star and the ratified work-record framework. Historical landing-zone text is retained only under “Honest history,” which is the correct pattern (do not erase the pivot). Residual **ecosystem** collisions (not INTENT text, but still real): | Location | Collision | | --- | --- | | activity-core `ISSUE_SINK_TYPE=rest` default | Still implements the banned always-on path until ACTIVITY-WP-0022 | | `pyproject.toml` description | Still “Authoritative task lifecycle manager…” (packaging drift) | | Registry capability summary | Still “coordination” framing toward multi-agent issue boards | | Older workplans / AGENT examples | May still read as “agents coordinate via issues” as primary | Those should not block INTENT; they are cleanup follow-ups. --- ## 6. Recommended INTENT edits (priority) | Priority | Edit | Why | | --- | --- | --- | | P1 | Split **Shipped** vs **Target** under “What it is” | Stop overstating mapping/boundary sync | | P1 | Fix diagram: file → (hub index) + optional project → issue-core → backends | Match ADR-001 topology | | P1 | Dual-lifecycle / boundary-sync discipline note | Prevent status-machine merge bugs | | P2 | UUIDv7 + canonical name wording | Match identity layering | | P2 | Point findings path at **intake + promotion**, not only “don’t IssueSink” | Close the operational gap | | P2 | Clarify unmapped issues are outside the work-record spine | Avoid informal parallel ontology | | P3 | Name full kind registry or link it once | Completeness | | P3 | Prefer “claim/execute” over overloaded “intake” for harness | Terminology | **Out of scope for INTENT alone:** Implementing mapping, changing IssueSink defaults, rewriting AGENT_INTEGRATION examples — those are separate work. --- ## 7. Consistency with SCOPE.md (2026-07-21) | Topic | INTENT | SCOPE inventory | Match? | | --- | --- | --- | --- | | Connector role | Yes | Yes | Yes | | Not work origin | Yes | §3.1 | Yes | | Mapping | Target | Design + not shipped | Yes if INTENT softens “What it is” | | Backends | SQLite + Gitea (+ planned) | Same | Yes | | REST TaskSpec | Optional intentional | Full contract | Yes | | State-hub runtime events from package | Downstream mention | Explicitly not shipped | Mild aspirational gap in older SCOPE; current SCOPE honest | INTENT and SCOPE are **compatible**; SCOPE is more operationally precise after the inventory rewrite. INTENT should borrow SCOPE’s shipped/not-shipped honesty without becoming a second inventory. --- ## 8. Conclusion **INTENT.md matches the work-record restructuring on the decisive axes:** - File-first work records vs tracker as optional external projection - Connector / mapping role per architecture §4.2 - Explicit rejection of landing-zone / default Forgejo spam - No parallel “issue” kind inside the closed registry **It collides only softly**, where language or diagrams can still be read as: - hub-centric mapping rather than file-centric origin, - UUID-only identity, - tracker states interchangeable with fleet statuses, - connector responsibilities already delivered, - or “stop IssueSink” without a named intake/promotion destination. **Suggested next step (superseded):** apply the P1/P2 INTENT edits… ### Remediation (2026-07-22) | Item | Status | | --- | --- | | P1–P3 INTENT edits (shipped vs target, diagram, dual lifecycle, UUIDv7 + canonical id, intake+promotion, unmapped outside spine, kind registry, claim/execute wording) | **Done** — `INTENT.md` rewritten 2026-07-22 | | Implementation of mapping / scope gaps | **Tracked** — `workplans/ISSUE-WP-0005-connector-alignment-implementation.md` | This report remains the audit trail; treat INTENT as current intent, not the pre-remediation text analyzed above. --- ## References - `INTENT.md` - `SCOPE.md` - `docs/uuid-external-id-mapping.md` - `workplans/ISSUE-WP-0004-align-with-work-record-canon.md` - `the-custodian/canon/standards/work-record-types_v0.1.md` - `the-custodian/research/WorkOrchestrationArchitectureDraft.md` (§1, §4.2, §8) - `the-custodian/canon/architecture/adr-001-workplans-as-repo-artefacts.md` - activity-core `workplans/ACTIVITY-WP-0022-issuesink-no-default-forgejo.md`