diff --git a/reconcile.go b/reconcile.go index 25a943b..cd343b0 100644 --- a/reconcile.go +++ b/reconcile.go @@ -120,18 +120,21 @@ func writeMarker(path, ref, short string) error { current = markerRE.ReplaceAllString(current, block) next = []byte(current) } else { - // Insert at the top of the body (after any YAML frontmatter). - // All other user content is preserved byte-for-byte below. + // Append at the bottom of the file so user persona sections + // (e.g. SOUL.md identity, AGENTS.md workspace instructions) + // stay prominent at the top. The Pilot directive is placed + // after all user content and after any YAML frontmatter. frontmatter, body := splitFrontmatter(current) + body = strings.TrimRight(body, "\n") sep := "" if frontmatter != "" && !strings.HasSuffix(frontmatter, "\n") { sep = "\n" } bodySep := "" - if body != "" && !strings.HasPrefix(body, "\n") { - bodySep = "\n" + if body != "" { + bodySep = "\n\n" } - next = []byte(frontmatter + sep + block + bodySep + body) + next = []byte(frontmatter + sep + body + bodySep + block) } } diff --git a/zz_skillinject_test.go b/zz_skillinject_test.go index 3f38819..9c8eb6f 100644 --- a/zz_skillinject_test.go +++ b/zz_skillinject_test.go @@ -169,11 +169,10 @@ func TestMarker_PreservesUserContent(t *testing.T) { } got := mustRead(t, hb) - // Marker now lives at TOP of body (not at bottom) so it dominates - // any competing first-action instructions later in the file. User - // content is preserved BELOW the marker. - if !strings.HasPrefix(got, "") { + t.Errorf("marker block not at bottom of file:\n%s", got) } if !strings.Contains(got, pre) { t.Errorf("user content lost from file:\n%s", got) @@ -203,8 +202,8 @@ func TestMarker_PreservesUserContent(t *testing.T) { } } -// Marker is injected at the top of the body (after any frontmatter) and -// preserves all existing user content below. +// Marker is appended at the bottom of the file (after all user content and +// after any YAML frontmatter) preserving user persona sections at the top. func TestMarker_PreservesUserContentBelow(t *testing.T) { t.Parallel() home := t.TempDir() @@ -239,9 +238,9 @@ Some other content stays. t.Errorf("user content lost (%q):\n%s", want, got) } } - // Marker is present and at the top. - if !strings.HasPrefix(got, "") { + t.Errorf("marker not at bottom of file:\n%s", got[len(got)-min(150,len(got)):]) } } @@ -271,16 +270,7 @@ func TestMarker_PreservesYAMLFrontmatter(t *testing.T) { if !strings.Contains(got, "User body.") { t.Errorf("body content lost") } - // Marker should be AFTER frontmatter, BEFORE body content. - idxFrontmatterEnd := strings.Index(got, "---\n") + len("---\n") - // Walk past possible additional ---\n - for strings.HasPrefix(got[idxFrontmatterEnd:], "---\n") || strings.HasPrefix(got[idxFrontmatterEnd:], "\n") { - if strings.HasPrefix(got[idxFrontmatterEnd:], "---\n") { - idxFrontmatterEnd += len("---\n") - } else { - break - } - } + // Marker should be AFTER frontmatter AND AFTER body content. idxMarker := strings.Index(got, "