247 lines
11 KiB
Markdown
247 lines
11 KiB
Markdown
---
|
|
id: CUST-ADR-001
|
|
type: architecture-decision-record
|
|
title: "Workplans and Work Items Are Repository Artefacts"
|
|
status: accepted
|
|
owner: the-custodian
|
|
revision: "accepted-2"
|
|
last_reviewed: "2026-08-31"
|
|
review_interval: 6m
|
|
decided_by: Bernd Worsch
|
|
date: "2026-02-28"
|
|
tags: ["architecture", "state-hub", "workplans", "source-of-truth", "rebuild-principle", "forgejo", "projection"]
|
|
---
|
|
|
|
# ADR-001: Workplans and Work Items Are Repository Artefacts
|
|
|
|
## Status
|
|
|
|
Accepted 2026-02-28.
|
|
|
|
Amended 2026-08-31 to distinguish file-backed work records from hub-native
|
|
records, identify the Forge default branch as the central projection baseline,
|
|
and align identity, lifecycle, reconciliation, and closure with ADR-007,
|
|
ADR-010, ADR-011, ADR-012, and the work-record standards. The central decision
|
|
is unchanged.
|
|
|
|
## Context
|
|
|
|
During early State Hub development, workstreams and tasks were created directly
|
|
in PostgreSQL through bootstrap APIs. This made a database the origin of durable
|
|
work rather than a projection of repository-owned artefacts. The pattern was
|
|
convenient, but it made work difficult to audit, review, recover, and carry
|
|
between generations of tooling.
|
|
|
|
The original decision correctly moved durable workplans and their work items
|
|
into repositories. It overstated the consequence, however, by saying that the
|
|
entire Hub database and every item that matters for coordination must be
|
|
reconstructible from repository files. Later decisions established two
|
|
different persistence classes:
|
|
|
|
- **file-backed records**, whose durable meaning originates in a repository;
|
|
- **hub-native records**, such as append-only progress and runtime facts, whose
|
|
durable meaning originates in the Hub.
|
|
|
|
Later decisions also established that a central projection reads the pushed
|
|
default branch in Forgejo. An arbitrary workstation checkout is a workspace,
|
|
not the shared baseline. Unpushed local work may be represented only as an
|
|
explicit preliminary overlay.
|
|
|
|
## Decision
|
|
|
|
### 1. File-backed work originates in the owning repository
|
|
|
|
Workplans and their file-backed work items **MUST originate as repository
|
|
artefacts in the repository that owns the work**. The Hub indexes and projects
|
|
those artefacts but is not their origin.
|
|
|
|
This includes the workplan, embedded tasks, declared dependencies, residual
|
|
handoffs, and durable governed decision artefacts when those are represented as
|
|
files. No authoritative field of a file-backed record may exist solely in a Hub
|
|
database.
|
|
|
|
The owning repository is identified by repository identity, not merely by a
|
|
domain or topic. Domains and topics classify work; they do not own its source.
|
|
|
|
### 2. Authority is explicit per persistence class
|
|
|
|
Every record contract must declare whether the record is file-backed or
|
|
hub-native. The same record must not be writable as authoritative in both
|
|
places.
|
|
|
|
- For a **file-backed record**, the repository artefact is authoritative and
|
|
the Hub row is derived state.
|
|
- For a **hub-native record**, the Hub is authoritative. Progress events,
|
|
messages, token events, run history, and similar runtime facts are not made
|
|
fictional repository records merely to satisfy a rebuild slogan.
|
|
|
|
The word `decision` is used by more than one subsystem. Architecture decisions
|
|
and other governed decision artefacts remain files. A runtime decision event may
|
|
be hub-native only where its schema says so explicitly; it does not replace the
|
|
governed artefact.
|
|
|
|
This replaces the original blanket rejection of a hybrid architecture. The
|
|
architecture is hybrid **by declared record class**, never ambiguous within one
|
|
record.
|
|
|
|
### 3. Forge is the central projection baseline
|
|
|
|
For the shared central view, the source is the pushed default-branch state held
|
|
by Forgejo, as decided by ADR-012. Every projected record must be attributable
|
|
to its source repository, path, and commit.
|
|
|
|
A working copy remains the authoring workspace. Unpushed work may appear in the
|
|
Hub only as an attributed preliminary overlay. It must not silently replace or
|
|
be presented as the Forge-derived baseline. When its commit reaches Forge, the
|
|
baseline absorbs it and the overlay retires.
|
|
|
|
### 4. Mutations of file-backed state are file-first
|
|
|
|
Creating or changing a file-backed work record means changing its repository
|
|
artefact first. A convenience tool or API is conformant only when it performs a
|
|
governed repository mutation and leaves a reviewable file and commit. Writing
|
|
only the projected database row is not a durable update.
|
|
|
|
Direct Hub APIs remain valid for hub-native records. They may also provide
|
|
diagnostics or propose repository patches, but a successful database PATCH is
|
|
not evidence that a file-backed status changed.
|
|
|
|
### 5. The rebuild guarantee applies to the projection, not the whole database
|
|
|
|
Given a repository and a specific Forge commit, the system must be able to
|
|
reconcile that repository's file-derived projection so that it is equivalent to
|
|
the records derived from that commit. Reconciliation must be idempotent,
|
|
verifiable, and scoped per repository; a fleet operation is iteration over the
|
|
same per-repository operation.
|
|
|
|
Reconciliation retires file-derived records that no longer derive. It does not
|
|
delete hub-native history attached to them. It must refuse and report a
|
|
repository whose records exist only in the projection until those records have
|
|
an explicit disposition. A Forge rebuild does not reconstruct preliminary
|
|
overlays and must disclose their retirement before proceeding.
|
|
|
|
Therefore the **file-derived projection is disposable**. The database as a
|
|
whole is not disposable when it also contains hub-native facts.
|
|
|
|
### 6. Identity and lifecycle are delegated contracts
|
|
|
|
This ADR does not define a second identity or lifecycle schema.
|
|
|
|
- Workplan and task identity follow ADR-007 as amended by ADR-011: global
|
|
identity is namespace-aware, and derivable Hub identifiers are governed by
|
|
that contract. Existing historical identifiers are grandfathered according
|
|
to its migration rules.
|
|
- Work-record kinds, locations, lifecycle values, and residual handling follow
|
|
`canon/standards/work-record-types_v0.1.md` and
|
|
`canon/standards/workplan-terminology-fleet_v0.1.md`.
|
|
|
|
New normative text uses `workplan` and `work record`. `workstream` remains only
|
|
as a metered compatibility term for legacy database and API surfaces.
|
|
|
|
### 7. Reconciliation belongs at the repository boundary
|
|
|
|
Repo Manager owns discovery, parsing, identity checks, and reconciliation for
|
|
file-backed records. State Hub owns the projection and hub-native records. The
|
|
implementation may distribute fetch and parse work, but it must preserve that
|
|
authority boundary.
|
|
|
|
Legacy `create_workstream`, `create_task`, workstation-driven
|
|
`sync-workplans`, and similarly named commands are not normative interfaces.
|
|
They are conformant only if their current implementation satisfies decisions
|
|
3 and 4; otherwise they are transitional or retired.
|
|
|
|
## Workplan closure
|
|
|
|
A workplan cannot be marked `finished` merely by changing its Hub row. Before
|
|
closure, the responsible worker must:
|
|
|
|
1. review the source file and the projected view for unfinished tasks;
|
|
2. record completed and cancelled outcomes in the source task blocks using the
|
|
canonical task lifecycle;
|
|
3. turn every actionable carry-forward item into a live work record with
|
|
`origin: residual` and an `origin_ref`, or into another explicitly linked
|
|
workplan;
|
|
4. set the source workplan to `finished`, update it, and commit the result;
|
|
5. publish the commit to Forge for the shared baseline and verify that the
|
|
projection reconciles to that commit.
|
|
|
|
A local reconciliation before push may expose preliminary state, but it does
|
|
not complete step 5.
|
|
|
|
Automated stale-task cleanup must report file/projection drift. It may not
|
|
silently cancel a file-backed task only in the database. An automated repair may
|
|
change such a task only through the same governed repository mutation and
|
|
commit path as any other file-backed change. Cleanup of hub-native records is
|
|
governed by their own retention contract.
|
|
|
|
## Consequences
|
|
|
|
### Positive
|
|
|
|
- Durable work remains inspectable, reviewable, and recoverable through Git.
|
|
- The central view has an exact repository and commit provenance instead of
|
|
reflecting whichever workstation synced most recently.
|
|
- Reconciliation can be exercised per repository without destroying progress
|
|
history or other hub-native evidence.
|
|
- Multiple contributors share a published baseline while retaining an honest
|
|
representation of preliminary work.
|
|
- Service ownership is clearer: repositories own file-backed truth; the Hub
|
|
owns runtime facts and projection services.
|
|
|
|
### Negative
|
|
|
|
- File-backed changes require a repository mutation and normally a push before
|
|
they become shared baseline state.
|
|
- Forge availability affects projection freshness, although it does not prevent
|
|
local authoring.
|
|
- Preliminary, stale, and retired projection states must be visible in APIs and
|
|
user interfaces.
|
|
- Git merge conflicts become the explicit conflict mechanism for simultaneous
|
|
edits to the same authoritative artefact.
|
|
- Tools that previously corrected only database state must be changed to emit a
|
|
diagnostic or perform a governed repository update.
|
|
|
|
## Migration
|
|
|
|
No bulk rename, UUID rewrite, or historical file rewrite is required by this
|
|
amendment. Existing identifiers and legacy terminology retain the grandfathering
|
|
rules of ADR-007, ADR-011, and the terminology standard.
|
|
|
|
Implementations must audit and retire DB-first creation, closure, and stale-task
|
|
cleanup paths. Existing file-backed projection rows without a Forge source
|
|
commit are migration state: they must be matched to a repository artefact or
|
|
explicitly dispositioned before reset. Forge-derived reconciliation and
|
|
preliminary overlays are implemented under ADR-012 rather than duplicated here.
|
|
|
|
The `accepted-1` publication remains the immutable historical revision. This
|
|
document is `accepted-2`.
|
|
|
|
## Alternatives considered
|
|
|
|
**Database-first with export.** Rejected. Export can be skipped, making the
|
|
reviewable artefact secondary and stale.
|
|
|
|
**Files only, with no projection database.** Rejected. Cross-repository queries,
|
|
runtime views, and append-only operational facts need indexed services.
|
|
|
|
**Treat every Hub record as reconstructible from Git.** Rejected. This either
|
|
loses runtime truth during rebuild or creates artificial files whose only
|
|
purpose is mirroring a database.
|
|
|
|
**Let working copies push authoritative projection rows.** Rejected by ADR-012.
|
|
It makes the baseline depend on the last workstation to reconcile and cannot be
|
|
audited against a shared commit.
|
|
|
|
## Related
|
|
|
|
- ADR-003 — materialized and derived state
|
|
- ADR-005 — cross-repository work ownership
|
|
- ADR-007 — workplan identity and repository worker topology
|
|
- ADR-010 — Hub authority and local cache model
|
|
- ADR-011 — namespace-aware federation and reconciliation limits
|
|
- ADR-012 — Forge projection source and preliminary overlay
|
|
- `canon/standards/work-record-types_v0.1.md` — work-record kinds, lifecycle,
|
|
residuals, and reconciliation
|
|
- `canon/standards/workplan-terminology-fleet_v0.1.md` — canonical terminology
|
|
- `canon/values/foundational_values_v0.1.md` — local-first operation,
|
|
auditability, and reversibility
|