Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion PRODUCT_SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,13 @@ The product shall provide a diagnostic command that validates publishing prerequ

## Title Rule

The first H1 heading becomes the issue title.
The first heading at the top of the markdown becomes the issue title.

Supported heading levels:

* H1
* H2
* H3

Example:

Expand All @@ -173,6 +179,8 @@ becomes
Add timestamps to logging system
```

The same rule applies to the first `##` or `###` heading when it appears at the top of the markdown.

---

## Body Rule
Expand Down
2 changes: 1 addition & 1 deletion TASKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

Acceptance Criteria:

* Markdown with a first H1 heading produces a valid issue draft
* Markdown with a first H1, H2, or H3 heading produces a valid issue draft
* Markdown without content is rejected
* Missing title is rejected

Expand Down
2 changes: 1 addition & 1 deletion internal/compliance/compliance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestFrameworkCompliance(t *testing.T) {

func TestArchitectureCompliance(t *testing.T) {
root := repoRoot(t)
assertContains(t, root, "PRODUCT_SPEC.md", "The first H1 heading becomes the issue title.")
assertContains(t, root, "PRODUCT_SPEC.md", "The first heading at the top of the markdown becomes the issue title.")
assertContains(t, root, "ARCHITECTURE.md", "Author != Publisher")
assertContains(t, root, "FRAMEWORK.md", "AST-based parsing")
assertContains(t, root, "FRAMEWORK.md", "Single Binary CLI")
Expand Down
2 changes: 1 addition & 1 deletion internal/extraction/extractor.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func extractTitleAndBody(md string) (string, string) {
return ast.WalkContinue, nil
}
heading, ok := node.(*ast.Heading)
if !ok || heading.Level != 1 {
if !ok || heading.Level < 1 || heading.Level > 3 {
return ast.WalkContinue, nil
}

Expand Down
14 changes: 14 additions & 0 deletions internal/extraction/extractor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,20 @@ func TestExtractIssue(t *testing.T) {
wantBody: "Current logs do not contain timestamps.",
wantErr: false,
},
{
name: "with h2 title",
content: "## Add timestamps to logging\n\nCurrent logs do not contain timestamps.",
wantTitle: "Add timestamps to logging",
wantBody: "Current logs do not contain timestamps.",
wantErr: false,
},
{
name: "with h3 title",
content: "### Add timestamps to logging\n\nCurrent logs do not contain timestamps.",
wantTitle: "Add timestamps to logging",
wantBody: "Current logs do not contain timestamps.",
wantErr: false,
},
{
name: "with inline code title",
content: "# Add `--version` Support\n\nBody text.",
Expand Down
Loading