Skip to content

I1516 — The adapter composes a projected body in one place

Make the body scripts/github-sync posts to an issue the same text it prints for that issue, by composing it once, so that a body the adapter wrote is a body the adapter recognises as its own.

DONE wave 0 · p0 · implementation profile · parallel safe

Part of work-graph-github — The projection to GitHub is gated, identified and traversable, and a merged pull request leads back to the outcome it served.

Objective

Make the body scripts/github-sync posts to an issue the same text it prints for that issue, by composing it once, so that a body the adapter wrote is a body the adapter recognises as its own.

Why

The adapter composed the generated region twice — once for --render and once for the splice that updates an issue that already exists — and the two compositions drifted. record_marker() prints without a trailing newline; --render wrapped it in printf '%s\\n' and the splice did not, so the first line of the record was glued to the marker in every body the splice posted. region_intact() drops the marker line before hashing the region back, and that prefix match took the glued first line with it, so such a region never hashed to what its own marker claimed. Every issue written through the splice was then classified `edited` — a person's hand-edit, never to be overwritten — and --force could not repair one, because it rewrote it exactly the same way. This is measured, not hypothetical: 19 of the 215 managed issues on GitHub carry a marker line with body text appended, and they are exactly the 19 findings that keep the github-projection gate red.

Current state

19 managed issues carry a concatenated marker line; scripts/ci/github-check exits 10 on them; the structure job fails on every branch that reaches it. test/cases/45 exercises only the --render composition, so the splice composition has never been tested at all. Refreshed onto master 2026-09-30 from PR #554: master still carries both compositions.

Desired state

One function composes the region's content, and both the rendering and the splice call it. Case 45 refuses a second composition and a caller that writes the marker without ending its line; case 602 drives --apply against a stubbed gh and reads the posted body back as insync. The 19 remote bodies are rewritten by --apply --force and the gate goes green.

Scope

  • scripts/github-sync
  • test/cases/45_github_projection.sh
  • test/cases/602_a_spliced_body_is_recognised_as_its_own.sh

Out of scope

  • The remote rewrite itself, which is an operation and not a change to the repository.
  • The drift baseline, which shrinks on its own once the bodies are correct.

Dependencies

None. This issue is a root of the graph.

Acceptance criteria

  • The region body is composed in exactly one place in the adapter
  • No caller writes the record marker without terminating its line
  • A body the splice would post classifies as insync, not edited

Validation

  • bash test/run.sh 45_github_projection
  • bash test/run.sh 602_a_spliced_body_is_recognised_as_its_own
  • bash scripts/ci/shell-lint

Evidence required

  • the_two_compositions_are_one
  • a_spliced_body_is_recognised_as_its_own

Evidence

coverstypecommandresultat commit
the_two_compositions_are_onetestbash test/run.sh 45_github_projectionok at b4a781c668: case 45 refuses a second composition and a marker written without ending its line; the fix is a19588c506 (PR #690)b4a781c
a_spliced_body_is_recognised_as_its_owntestbash test/run.sh 602_a_spliced_body_is_recognised_as_its_own; scripts/ci/github-checkok at b4a781c668: the body --apply posts reads back insync; github-check against the live remote reports 0 finding(s), 0 record(s) adoptb4a781c

Risk

Low. The change removes a duplicate definition; the rendering it keeps is the one every other surface already prints.

Timeline

started
2026-09-15
verified
2026-10-07T13:27:22Z
completed
2026-10-07T13:27:24Z

Those three fields, the evidence above and the state of the dependencies are all the status is made of. There is no status field to disagree with them.

Canonical record: .ai/repo/project/issues/I1516.yaml. Read it back with majordomus plan show I1516.

Searches the titles and descriptions of every page this site publishes.