Skip to content

fix: goal-creator now emits task_identifier - #92

Closed
bborbe wants to merge 1 commit into
masterfrom
fix-goal-creator-task-identifier
Closed

fix: goal-creator now emits task_identifier#92
bborbe wants to merge 1 commit into
masterfrom
fix-goal-creator-task-identifier

Conversation

@bborbe

@bborbe bborbe commented Aug 17, 2026

Copy link
Copy Markdown
Owner

Problem

goal-creator never emitted task_identifier, so every goal it created failed goal lint on the first check:

ERROR 23 Goals/<goal>.md: MISSING_TASK_IDENTIFIER task_identifier is missing; run backfill to assign one

goal lint --fix does not repair it, so the operator has to generate a UUID by hand and run goal set.

task-creator.md has carried the equivalent instruction all along (agents/task-creator.md:120) — the goal side was simply missing it.

Fix

One line added to the required-frontmatter list in agents/goal-creator.md, mirroring the task-creator wording.

Evidence

Found 2026-08-17 while scaffolding a goal via /jira-sprint-sync: all five sibling tasks created by task-creator in the same run linted clean, and only the goal failed.

Not fixed here

The lint hint names a backfill command that does not exist on vault-cli goal, and goal lint --fix reports MISSING_TASK_IDENTIFIER as fixable without fixing it. Both are Go-side; this change makes the common path moot but does not address them.

@bborbe

bborbe commented Aug 17, 2026

Copy link
Copy Markdown
Owner Author

Closing unmerged — the premise was wrong.

I proposed this after goal lint failed a freshly created goal with MISSING_TASK_IDENTIFIER, and agents/task-creator.md carried the instruction while goal-creator.md did not. I treated that asymmetry as the defect. It isn't.

Checking what goals actually contain:

  • 19 goals in the Brogrammers vault; 1 carries task_identifier — the one I set by hand while investigating.
  • goal_identifier: appears in 6 goals across vaults. That, not task_identifier, is the goal-side key.

So this PR would have written a task-shaped key onto every future goal.

The real defect is in the linter: pkg/ops/lint.go runs missingTaskIdentifierIssues on every file with no page-type branch, and detectMissingTaskIdentifier unmarshals only yaml:"task_identifier". Goals get checked for the wrong key — all 19 fail it, not just newly created ones. grep -rn goal_identifier --include='*.go' returns nothing, so the Go side has never modelled the key goals actually use.

Two adjacent findings for whoever picks up the real fix:

  • pkg/storage/task.go:44 auto-generates the UUID in WriteTask when empty; WriteGoal in pkg/storage/goal.go has no equivalent.
  • EnsureAllTaskIdentifiersOperation exists in pkg/ops but is wired to no CLI command, so the lint hint "run backfill to assign one" names something uninvokable.

Correct fix: make the identifier check page-type aware, or unify both page types behind one neutral key. Either needs a spec, not a one-line agent edit.

@bborbe bborbe closed this Aug 17, 2026
@bborbe
bborbe deleted the fix-goal-creator-task-identifier branch August 17, 2026 07:35

@ben-s-pull-request-reviewer ben-s-pull-request-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now have all the information needed for a thorough review.

Summary of review:

The diff contains exactly two files: CHANGELOG.md (one changelog bullet) and agents/goal-creator.md (one instruction line added to the "Required fields" list in step 8).

Key architectural facts established by code inspection:

  1. GoalFrontmatter has no TaskIdentifier() accessor — unlike TaskFrontmatter which has both TaskIdentifier() and SetTaskIdentifier(). However, GoalFrontmatter embeds FrontmatterMap and uses GetString(key) for unknown fields, so task_identifier written by the agent will survive round-trips via the generic path (e.g., GetField("task_identifier")). The field is not lost — it's just not accessed via a typed method.

  2. No Go code creates goalsdomain.NewGoal() takes a plain map[string]any; callers populate it. The goal-creator agent (a markdown/Claude instruction file) is what generates the actual file content. The fix is correctly placed in the agent instruction file.

  3. MISSING_TASK_IDENTIFIER fixabilityFixable: false is intentional (auto-minting a UUID would silently change identity). The lint message says "run backfill" but the changelog accurately notes this command does not exist. This is a pre-existing UX defect in lint.go:621, not introduced by this PR, and correctly documented in the changelog.

  4. Changelog accuracy — The bullet accurately describes the bug, the discovery context, and the two related observations (sibling tasks linting clean; backfill command absent).


{
  "verdict": "approve",
  "summary": "Clean documentation-only fix. The goal-creator agent now instructs itself to emit `task_identifier` in generated goal frontmatter, matching the existing convention in task-creator. No Go code changes; the field survives round-trips via FrontmatterMap. The changelog entry accurately describes the bug, its discovery context, and the related backfill-command UX issue.",
  "comments": [],
  "concerns_addressed": [
    "correctness: agents/goal-creator.md is documentation-only (markdown agent definition); confirmed — no Go code creates goals, the agent instruction is the correct fix location",
    "correctness: goal lint --fix reports MISSING_TASK_IDENTIFIER as fixable without actually fixing it — accurately documented in the CHANGELOG.md bullet; pre-existing lint.go UX defect, not introduced by this PR"
  ]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant