Read acceptance criteria from one recognized issue section

Gitea ingest set title, description and capability but never acceptance, so
every Gitea-sourced task rendered "Acceptance: Not stated." however carefully
its body was written. F2 restored the body; it did not wire the field.

The convention is deliberately tiny. A markdown heading spelled "acceptance"
or "acceptance criteria" opens the section, bullet and checklist items until
the next heading become the criteria in order, checkbox markers are stripped,
empty items are dropped, and the whole section leaves the description so a
criterion is never also read as instruction prose. Nothing else is recognized:
inferring acceptance from arbitrary prose would eventually invent a
requirement, and a fabricated criterion outranks every human decision beneath
it in the authority order.

An absent section yields no acceptance, which is not an ingestion failure. The
task renders "Not stated." and the frame phase resolves it through the
decision-request path, where a human answers instead of the parser guessing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-27 00:35:37 +04:00
parent 0d67af9976
commit a5d361b59f
3 changed files with 165 additions and 1 deletions
+29
View File
@@ -277,3 +277,32 @@ func assertBefore(t *testing.T, ctx, first, second string) {
t.Fatalf("%q must precede %q:\n%s", first, second, ctx)
}
}
// Ingested acceptance criteria must reach the rendered task in order, and an
// absent one must say so rather than be silently omitted.
func TestAcceptanceCriteriaRenderInOrder(t *testing.T) {
in := input()
in.Task.Acceptance = []string{"labelled score does not regress", "targeted cases improve"}
in.Intent.Task = in.Task
got, err := Build(in)
if err != nil {
t.Fatal(err)
}
first := strings.Index(got.Task, "- labelled score does not regress")
second := strings.Index(got.Task, "- targeted cases improve")
if first < 0 || second < 0 {
t.Fatalf("acceptance criteria missing from rendered task:\n%s", got.Task)
}
if first > second {
t.Fatal("acceptance criteria rendered out of order")
}
in.Task.Acceptance = nil
in.Intent.Task = in.Task
got, err = Build(in)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(got.Task, "## Acceptance\n\nNot stated.") {
t.Fatalf("absent acceptance did not render Not stated:\n%s", got.Task)
}
}