#278 extracted submitOnReturnInsertNewlineOnShift (Sources/Helm/Shared/SubmitOnReturn.swift) and routed the Archon rail and the canvas comment field through it. ChatComposer — the caller the rule was first written for, in #119/#275 — still spells the same five lines out inline:
.onSubmit(submit)
.onKeyPress(.return, phases: [.down, .repeat], action: startALine)
It was left alone because Sources/Helm/Chat/ was another slice's file and in flight while #278 was being built, not because the duplicate is justified. There is no runtime boundary here — Chat/ and Shared/ are the same target, compiled by the same swift build — so it does not earn the carve-out AGENTS.md gives hooks//pi/ and the spool scripts.
What to do
Replace the two lines above with .submitOnReturnInsertNewlineOnShift(submit: submit, insertNewline: startALine) and reduce startALine to draft += "\n" (it currently takes a KeyPress and does the shift guard, which the modifier now owns). ChatComposer's long doc comment on startALine can point at the modifier's header rather than restating it.
ChatComposerReturnTests should stay exactly as it is and stay green — it is the proof the conversion changed no behaviour, including its held-Shift+Return case.
What is watching in the meantime
SubmitOnReturnParityTests reads both files and fails if the inline copy's phase set or shift guard stops matching the modifier's. It also fails once this conversion lands — its subject is the duplicate, and the duplicate is what you are removing. Delete it in the same commit and say so, per AGENTS.md.
#278 extracted
submitOnReturnInsertNewlineOnShift(Sources/Helm/Shared/SubmitOnReturn.swift) and routed the Archon rail and the canvas comment field through it.ChatComposer— the caller the rule was first written for, in #119/#275 — still spells the same five lines out inline:It was left alone because
Sources/Helm/Chat/was another slice's file and in flight while #278 was being built, not because the duplicate is justified. There is no runtime boundary here —Chat/andShared/are the same target, compiled by the sameswift build— so it does not earn the carve-outAGENTS.mdgiveshooks//pi/and the spool scripts.What to do
Replace the two lines above with
.submitOnReturnInsertNewlineOnShift(submit: submit, insertNewline: startALine)and reducestartALinetodraft += "\n"(it currently takes aKeyPressand does the shift guard, which the modifier now owns).ChatComposer's long doc comment onstartALinecan point at the modifier's header rather than restating it.ChatComposerReturnTestsshould stay exactly as it is and stay green — it is the proof the conversion changed no behaviour, including its held-Shift+Return case.What is watching in the meantime
SubmitOnReturnParityTestsreads both files and fails if the inline copy's phase set or shift guard stops matching the modifier's. It also fails once this conversion lands — its subject is the duplicate, and the duplicate is what you are removing. Delete it in the same commit and say so, perAGENTS.md.