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
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
| covers | type | command | result | at commit |
|---|---|---|---|---|
| the_two_compositions_are_one | test | bash test/run.sh 45_github_projection | ok 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_own | test | bash test/run.sh 602_a_spliced_body_is_recognised_as_its_own; scripts/ci/github-check | ok at b4a781c668: the body --apply posts reads back insync; github-check against the live remote reports 0 finding(s), 0 record(s) adopt | b4a781c |
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.