Skip to content

feat(jtk): INT-693 clear fields with an empty value; none/null clear numbers - #471

Merged
piekstra merged 1 commit into
mainfrom
piekstra/INT-693-field-clear-signed
Aug 7, 2026
Merged

feat(jtk): INT-693 clear fields with an empty value; none/null clear numbers#471
piekstra merged 1 commit into
mainfrom
piekstra/INT-693-field-clear-signed

Conversation

@piekstra

@piekstra piekstra commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

[INT-693]

Signed replacement of #470 — that branch's commits were unsigned and the main ruleset requires verified signatures. This commit was created via GitHub's API (GitHub-signed, verified) and its tree SHA (cd407189) is identical to #470's reviewed head, so the content is byte-for-byte what cr APPROVED there with all CI green and its one finding (issuelink clear-on-empty test) addressed.

jtk issues update -f 'Story Points=' (or =none) previously failed with Jira's per-type validation error because FormatFieldValue only honored null-intent for user fields; there was no way to unset a custom field from the CLI.

The contract

  • Empty value clears every structured type (number, option, array, priority-like, issuelink, parent) → JSON null
  • none/null additionally clear number fields, matching user-field behavior
  • Option-like fields do NOT treat None as a clear — a select list may contain a literal "None"
  • Free-text unchanged: verbatim value; empty string is the idiomatic text clear

Validation

TestFormatFieldValue_Clearing covers every clear branch incl. issuelink; full tools/jtk suite green; gofmt clean.

…numbers

An empty value now clears (JSON null) every structured field type - number,
option, array, priority-like, issuelink, parent - and none/null additionally
clear number fields, matching the existing user-field behavior. Previously
FormatFieldValue only honored null-intent for user fields; a number field
fell through to ParseFloat and sent the raw string, so Jira rejected every
attempt to unset Story Points, and there was no way to unset a custom field
from the CLI at all.

Option-like fields deliberately do not treat the string None as a clear: a
select list may legitimately contain an option named None. Free-text fields
keep the verbatim value - empty string is the idiomatic text clear.

[INT-693]

@monit-reviewer monit-reviewer 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.

Automated PR Review

Reviewed commit: 43cf2f65e2f2
Profile: claude-monit-reviewer - Posting as: monit-reviewer

Summary

Reviewer Findings
go:implementation-tests 1
policies:conventions 0
go:implementation-tests (1 finding)

Minor - tools/jtk/api/fields_test.go:950

TestFormatFieldValue_Clearing tests that the option branch keeps a literal "None" value (since a select list may legitimately have an option named "None"), but the priority/resolution/status/issuetype/securitylevel branch — which shares the exact same name-addressed, non-none-clearing contract per the new doc comment — has no equivalent case. This is the one branch in the group where the untested edge is realistic rather than hypothetical: Jira ships a built-in Priority literally named "None" in many instances, so --field priority=None hitting this code path is a real, not speculative, scenario, and it's exactly the case the PR's contract calls out ("a select list or priority scheme may legitimately contain an entry named 'None'"). Add a case mirroring "option keeps the literal string None" for a priority-typed field (e.g. {name: "priority keeps the literal string None", field: priorityField, value: "None", want: map[string]string{"name": "None"}}) to lock in the behavior the doc comment promises.

Reviewer Coverage

  • go:implementation-tests — complete (broad); skipped: none; constraints: none
  • policies:conventions — complete (broad); inspected 2 assigned files (3 inspected across reviewers): tools/jtk/api/fields.go, tools/jtk/internal/cmd/issues/update.go; skipped: none; constraints: none
Inspected files (3)
  • tools/jtk/api/fields.go
  • tools/jtk/api/fields_test.go
  • tools/jtk/internal/cmd/issues/update.go

0 PR discussion threads considered. 0 summarized; 0 resolved.


Completed in 2m 19s | ~$1.79 (est.) | claude-sonnet-5 | cr 0.10.282
Field Value
Model claude-sonnet-5
Reviewers go:implementation-tests, policies:conventions
Engine claude_cli · claude-sonnet-5
Reviewed by cr · monit-reviewer
Duration 2m 19s wall · 3m 07s compute
Cost ~$1.79 (est.)
Tokens 42 in / 10.8k out

Per-workstream usage

  • orchestrator-selection — claude-sonnet-5
    • In: 6
    • Out: 3.3k
    • Cache read: 97.7k
    • Cache create: 76.8k
    • Cost: ~$0.37 (est.)
    • Duration: 50s
  • go:implementation-tests — claude-sonnet-5
    • In: 10
    • Out: 3.4k
    • Cache read: 250.9k
    • Cache create: 79.3k
    • Cost: ~$0.42 (est.)
    • Duration: 59s
  • policies:conventions — claude-sonnet-5
    • In: 20
    • Out: 3.7k
    • Cache read: 677.9k
    • Cache create: 95.0k
    • Cost: ~$0.61 (est.)
    • Duration: 1m 04s
  • orchestrator-rollup — claude-sonnet-5
    • In: 6
    • Out: 438
    • Cache read: 103.6k
    • Cache create: 93.1k
    • Cost: ~$0.39 (est.)
    • Duration: 12s

Comment thread tools/jtk/api/fields_test.go
@piekstra
piekstra merged commit b0f0114 into main Aug 7, 2026
10 checks passed
@piekstra
piekstra deleted the piekstra/INT-693-field-clear-signed branch August 7, 2026 15:43
piekstra added a commit that referenced this pull request Aug 7, 2026
## [INT-693]

Fast-follow to #471, addressing its review finding: the name-addressed
branch (priority/resolution/status/issuetype/securitylevel) shares the
only-empty-clears contract but had no literal-`None` case — and Jira
ships a built-in Priority literally named "None" in many instances, so
`--field priority=None` hitting that path is a real scenario.

One test-table case: `priority=None` → `{"name": "None"}`, mirroring the
existing option-field case. GitHub-signed commit (the `main` ruleset
requires verified signatures).
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.

2 participants