docs: INTENT.md vs work-record framework alignment review
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s

Audit INTENT against the ratified work-record types standard, ADR-001, and
architecture draft §4.2. Records alignments, soft frictions, dual-lifecycle
gaps, and recommended INTENT edits; no hard north-star collisions found.
This commit is contained in:
tegwick 2026-07-21 23:53:44 +02:00
parent bbbc5819c5
commit e804c4e15f

View file

@ -0,0 +1,339 @@
# 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 “dont 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. INTENTs 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-cores 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. INTENTs “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 drafts 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
INTENTs “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 INTENTs 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 “dont 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 SCOPEs 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:** apply the P1/P2 INTENT edits in a small docs PR (or
follow-up session); keep this report as the audit trail.
---
## 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`