From 6390b7beada367eb9c19619de83ba8a00155b5b3 Mon Sep 17 00:00:00 2001 From: tegwick Date: Tue, 25 Aug 2026 23:29:24 +0200 Subject: [PATCH] feat(workplan): open STATE-WP-0083 for the forge-derived projection reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements ADR-012 decision 7. Placed in state-hub because central must do its own reading: the pod can clone Forgejo anonymously, and driving this from Repo Manager would push a workstation-computed projection into central, which ADR-010 decision 5 forbids. Also the only sanctioned removal path — the hub has no hard-delete for work records by design. Co-Authored-By: Claude Opus 5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 2583210@bnt-lap001 Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006 --- ...-WP-0083-forge-derived-projection-reset.md | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 workplans/STATE-WP-0083-forge-derived-projection-reset.md diff --git a/workplans/STATE-WP-0083-forge-derived-projection-reset.md b/workplans/STATE-WP-0083-forge-derived-projection-reset.md new file mode 100644 index 0000000..bd8c560 --- /dev/null +++ b/workplans/STATE-WP-0083-forge-derived-projection-reset.md @@ -0,0 +1,146 @@ +--- +id: STATE-WP-0083 +type: workplan +title: "Forge-derived projection reset, per repository" +domain: infotech +repo: state-hub +status: active +owner: codex +topic_slug: infotech +created: "2026-08-25" +updated: "2026-08-25" +related: + - CUST-ADR-012 + - CUST-WP-0068 +--- + +# Forge-derived projection reset, per repository + +## Goal + +Implement `ADR-012` decision 7: discard a repository's projection and rebuild it +from what Forgejo holds. Per repository, routine, idempotent, and verifiable. + +This is the only sanctioned way to remove a hub record. The hub has no +hard-delete for work records — `DELETE /tasks/{id}` is `cancel_task`, +`DELETE /workstreams/{id}` is `410 Gone`, and no `session.delete` exists for +either. Re-derivation is not one option among several; it is the mechanism. + +## Why here and not in Repo Manager + +`ADR-012` decision 1 says central derives from the forge, and the pod can reach +it: `git ls-remote https://forgejo.coulomb.social/...` succeeds anonymously from +inside the cluster, and `git` is already in the image. + +Driving the reset from Repo Manager would mean computing a projection on a +workstation and pushing it into central — precisely the injection of derived +state `ADR-010` decision 5 forbids. Central must do its own reading. The cost is +that workplan parsing exists in two places; `scripts/consistency_check.py` +already parses frontmatter and task blocks here, so the capability is present +and should be extracted rather than rewritten. + +## What it must not do + +- **Not restore preliminary overlay records.** They exist because the forge does + not hold them; a rebuild from the forge cannot reproduce them and must not + pretend to. +- **Not destroy hub-native records.** Progress events, decisions and inbox + messages originate in the hub (`ADR-010` decision 4). They are not + forge-derived and must survive a rebuild of forge-derived state. +- **Not proceed silently when records would be lost.** Stop, name them, and + require an explicit acknowledgement. + +## Derive a repository's projection from the forge + +```task +id: STATE-WP-0083-T01 +status: todo +priority: high +``` + +Given a repository slug, clone or fetch its default branch from Forgejo into a +temporary location, parse the workplan files, and compute the projection that +state would produce: workplans, tasks, their identifiers, statuses and backing +paths. + +Read-only and side-effect free. Record the commit the derivation came from — +`ADR-012` decision 2 requires provenance, and the existing `git_fingerprint` is +worthless precisely because nothing ever wrote it correctly. + +Acceptance: deriving `the-custodian` twice from the same commit yields identical +output, and the commit is reported. + +## Report the difference before changing anything + +```task +id: STATE-WP-0083-T02 +status: todo +priority: high +``` + +Compare the derived projection against what the hub currently holds for that +repository, and report: records the forge has that the hub lacks, records the +hub has that the forge does not, and records whose fields differ. + +This is the half that is immediately useful without any destructive capability, +and it is what makes decision 7's "verifiable" real. It also answers the +question `CUST-WP-0068-T09` is waiting on — which stale rows would actually +clear — before anyone commits to clearing them. + +Acceptance: a dry-run diff for a repository with known drift matches what +manual inspection shows. + +## Apply the reset transactionally + +```task +id: STATE-WP-0083-T03 +status: todo +priority: high +``` + +Replace the repository's forge-derived records with the derived projection in +one transaction: create what is missing, update what differs, remove what no +longer derives. Hub-native records are untouched. + +Refuse by default when removal would destroy a record with no counterpart in the +forge; report what would be lost and require an explicit acknowledgement to +proceed. That refusal is evaluated per repository, so one unresolved repository +never blocks the rest. + +Acceptance: reset twice produces the same projection; a repository holding +records the forge lacks is refused with those records named; hub-native record +counts are unchanged across a reset. + +## Fleet form as a loop over the repository form + +```task +id: STATE-WP-0083-T04 +status: todo +priority: medium +``` + +The fleet-wide reset iterates the per-repository reset and shares its +implementation, so the rarely-used dangerous path is exercised by the frequently +used safe one. Repositories that refuse are skipped and reported, never aborting +the pass. + +Acceptance: a fleet dry-run reports per-repository outcomes including refusals, +and completes despite them. + +## Retire what the reset replaces + +```task +id: STATE-WP-0083-T05 +status: wait +priority: medium +``` + +Once reset is trusted, `CUST-WP-0068-T09` can clear its stale rows — 4 workplan +rows from the prefix migration and 305 task rows across 44 workplans. + +`ADR-003` decision 2's `mtime`-based fingerprints should also be replaced by the +source commit at this point; `ADR-012` invalidated that composition and the +replacement belongs with the provenance work in `T01`. + +Acceptance: `CUST-WP-0068-T09` closes; no fingerprint input depends on a local +filesystem.