From b61b86a3a0c4a8a2821dad45fbb7a80b78a9fec7 Mon Sep 17 00:00:00 2001 From: Rian Stockbower Date: Fri, 17 Jul 2026 14:52:32 -0400 Subject: [PATCH 1/2] docs: fix stale -o json chaos row and guard all-pages loop exit status Two leftover findings from #455 review that landed in approving rounds: - chaos-testing.md: -o json page-view row said PASS/Valid JSON, but resource JSON was removed in #392 and now errors at the root. - SearchIssues.md: the collect-all-pages loop did not check the jtk issues list exit status, so a failed page silently truncated results. Guard the command substitution and abort on failure. --- skills/Jira/Workflows/SearchIssues.md | 5 ++++- tools/cfl/chaos-testing.md | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/skills/Jira/Workflows/SearchIssues.md b/skills/Jira/Workflows/SearchIssues.md index 9db3b9ff..4c07b6f8 100644 --- a/skills/Jira/Workflows/SearchIssues.md +++ b/skills/Jira/Workflows/SearchIssues.md @@ -107,7 +107,10 @@ jtk issues list --project KEY --sprint current --id | xargs -I{} jtk issues get # Collect ALL keys across pages by iterating the stderr continuation token token="" while :; do - keys=$(jtk issues list --project KEY --id ${token:+--next-page-token "$token"} 2>/tmp/jtk-page-info) + if ! keys=$(jtk issues list --project KEY --id ${token:+--next-page-token "$token"} 2>/tmp/jtk-page-info); then + echo "jtk issues list failed; aborting to avoid a partial result set" >&2 + exit 1 + fi printf '%s\n' "$keys" token=$(grep -oE 'next: [^)]+' /tmp/jtk-page-info | cut -d' ' -f2) || break [ -z "$token" ] && break diff --git a/tools/cfl/chaos-testing.md b/tools/cfl/chaos-testing.md index bfe43ada..94c95216 100644 --- a/tools/cfl/chaos-testing.md +++ b/tools/cfl/chaos-testing.md @@ -84,7 +84,7 @@ Things where the current behavior might be correct, but we should confirm: | Non-numeric ID (abc) | PASS | Good 400 error | | Missing page ID | PASS | "accepts 1 arg(s)" error | | `--body-format xhtml` mode | PASS | Shows exact Confluence storage XHTML | -| `-o json` | PASS | Valid JSON (no trailing message!) | +| `-o json` | OBSOLETE | Historical PASS; resource JSON removed in #392, now errors at root ("invalid output format") | | Confluence macros | BUG-005 | TOC macro params leak through | ### Attachments From 247413b1986c3f6c541ac62ed41ff222d657ef29 Mon Sep 17 00:00:00 2001 From: Rian Stockbower Date: Fri, 17 Jul 2026 15:02:52 -0400 Subject: [PATCH 2/2] docs: remove -o json/-o yaml tombstones for the removed resource JSON surface Resource JSON output was removed in #392, but the cfl test docs still carried struck-through 'obsolete' rows and checklist items walking through it, plus a chaos-session log that recorded its behavior. Delete those entirely rather than documenting a surface that no longer exists; keep only the live contract statements (OUTPUT_SPEC, ARTIFACT_CONTRACT, changelog, README breaking-change note). Also drop a stale -o json reference from an attachment list test comment. --- tools/cfl/chaos-testing.md | 16 ++----------- tools/cfl/integration-tests.md | 24 +------------------ .../cfl/internal/cmd/attachment/list_test.go | 3 +-- tools/cfl/test-plan-writes.md | 6 +---- 4 files changed, 5 insertions(+), 44 deletions(-) diff --git a/tools/cfl/chaos-testing.md b/tools/cfl/chaos-testing.md index 94c95216..12102a6b 100644 --- a/tools/cfl/chaos-testing.md +++ b/tools/cfl/chaos-testing.md @@ -3,12 +3,6 @@ **Started:** 2026-01-03 **Focus:** Read-only operations (list, view, download) -> **Historical note (#392):** The `-o json` rows below describe behavior from -> a session that pre-dates the removal of resource-read JSON. As of #392 the -> closed set is `{table, plain}`; the `-o json` and `-o yaml` rows below are -> no longer reproducible — both now error at the root with the same -> "invalid output format" message. - --- ## Bugs Found @@ -17,8 +11,6 @@ |----|----------|-------------|-------------|--------| | BUG-001 | Medium | `--limit 0` silently uses default (25) instead of returning 0 or error | `cfl space list --limit 0` | **FIXED** | | BUG-002 | Medium | `--limit -1` silently uses default (25) instead of error | `cfl space list --limit -1` | **FIXED** | -| BUG-003 | High | JSON output for `space list` includes trailing message, breaking JSON parsing | `cfl space list -o json \| jq .` fails | **FIXED** | -| BUG-004 | Low | `-o yaml` silently falls back to table format instead of erroring | `cfl space list -o yaml` | **FIXED** | | BUG-005 | Low | Confluence macro parameters leak into markdown output | View page with TOC macro, see "12" artifact | **FIXED** | | BUG-006 | **CRITICAL** | `attachment download` panics - flag shorthand conflict | `cfl attachment download ` crashes with `-o` conflict | **FIXED** | @@ -65,9 +57,7 @@ Things where the current behavior might be correct, but we should confirm: | `--type personal` | PASS | Filters correctly | | `--type GLOBAL` | PASS | Case insensitive (API handles) | | `--type invalid` | PASS | Good error from API | -| `-o json` | BUG | Invalid JSON due to trailing message | | `-o plain` | PASS | Tab-separated, but has trailing message | -| `-o yaml` | BUG | Silently falls back to table | ### Page Listing (`cfl page list`) | Test | Result | Notes | @@ -84,7 +74,6 @@ Things where the current behavior might be correct, but we should confirm: | Non-numeric ID (abc) | PASS | Good 400 error | | Missing page ID | PASS | "accepts 1 arg(s)" error | | `--body-format xhtml` mode | PASS | Shows exact Confluence storage XHTML | -| `-o json` | OBSOLETE | Historical PASS; resource JSON removed in #392, now errors at root ("invalid output format") | | Confluence macros | BUG-005 | TOC macro params leak through | ### Attachments @@ -106,11 +95,10 @@ Things where the current behavior might be correct, but we should confirm: ## Summary -**6 bugs found (ALL FIXED):** +**4 bugs found (ALL FIXED):** - 1 CRITICAL (panic crash) - FIXED: Changed `-o` shorthand to `-O` for `--output-file` -- 1 HIGH (broken JSON output) - FIXED: Pagination message now goes to stderr - 2 MEDIUM (silent limit issues) - FIXED: Limit validation (negative = error, 0 = empty list) -- 2 LOW (minor UX issues) - FIXED: Output format validation + macro stripping +- 1 LOW (macro UX) - FIXED: Confluence macro stripping **Tests passed:** ~25 **Tests failed:** 0 (all bugs fixed) diff --git a/tools/cfl/integration-tests.md b/tools/cfl/integration-tests.md index 53972a05..f83bef89 100644 --- a/tools/cfl/integration-tests.md +++ b/tools/cfl/integration-tests.md @@ -2,8 +2,6 @@ This document catalogs the manual integration test suite for `cfl`. These tests verify real-world behavior against a live Confluence instance and catch edge cases that are difficult to cover with unit tests. -> **#392 update:** Rows that exercise `-o json` / `--output json` on resource commands are obsolete — the resource JSON surface has been removed. They now error at the root with `invalid output format: "json" (valid formats: table, plain)`. Skip those rows. The surviving JSON surface is `cfl set-credential --json` (control-plane envelope per cli-common §1.5.2); test that one normally. - ## Auth Methods cfl supports two authentication methods. The full integration test suite should be run with both: @@ -63,7 +61,6 @@ All cfl commands should work with both auth methods (no scope limitations for Co |-----------|---------|-----------------| | List pages in space | `cfl page list --space confluence` | Shows table of pages with ID, title, status, version | | List with limit | `cfl page list --space confluence --limit 5` | Shows only 5 pages with "showing first N results" message | -| ~~JSON output~~ (#392 removed) | `cfl page list --space confluence --output json` | Errors: invalid output format | | Plain output | `cfl page list --space confluence --output plain` | Tab-separated values | | List trashed pages | `cfl page list --space confluence --status trashed` | Shows deleted pages | | List archived pages | `cfl page list --space confluence --status archived` | Shows archived pages | @@ -76,13 +73,11 @@ All cfl commands should work with both auth methods (no scope limitations for Co | View page content | `cfl page view ` | Shows title, ID, version, and markdown content | | View exact XHTML | `cfl page view --body-format xhtml` | Shows exact Confluence storage XHTML | | View exact ADF | `cfl page view --body-format adf` | Shows exact ADF JSON | -| ~~JSON output~~ (#392 removed) | `cfl page view --output json` | Errors: invalid output format | | Non-existent page | `cfl page view 99999999999` | Error: 404 not found | | View content only | `cfl page view --content-only` | Markdown only, no Title/ID/Version headers | | Content only with XHTML | `cfl page view --content-only --body-format xhtml` | XHTML only, no headers | | Content only with macros | `cfl page view --content-only --show-macros` | Markdown with [TOC] etc., no headers | | Roundtrip macros (content-only) | `cfl page view --show-macros --content-only \| cfl page edit --legacy` | Macros preserved | -| ~~Content only JSON error~~ (#392 removed; -o json itself errors before --content-only checks) | `cfl page view --content-only -o json` | Errors: invalid output format | | Content only web error | `cfl page view --content-only --web` | Error: incompatible flags | ### page create @@ -155,7 +150,6 @@ All cfl commands should work with both auth methods (no scope limitations for Co |-----------|---------|-----------------| | List attachments | `cfl attachment list --page ` | Table of attachments with ID, title, type, size | | No attachments | List on page with none | "No attachments found" | -| ~~JSON output~~ (#392 removed) | `cfl attachment list --page --output json` | Errors: invalid output format | | List unused attachments | `cfl attachment list --page --unused` | Only attachments not referenced in page content | | No unused attachments | `--unused` on page using all attachments | "No unused attachments found" | @@ -199,7 +193,6 @@ All cfl commands should work with both auth methods (no scope limitations for Co | Test Case | Command | Expected Result | |-----------|---------|-----------------| | List all spaces | `cfl space list` | Table of spaces with key, name, type | -| ~~JSON output~~ (#392 removed) | `cfl space list --output json` | Errors: invalid output format | | Limit results | `cfl space list --limit 5` | Shows first 5 spaces | ### space view @@ -207,7 +200,6 @@ All cfl commands should work with both auth methods (no scope limitations for Co | Test Case | Command | Expected Result | |-----------|---------|-----------------| | View space by key | `cfl space view confluence` | Key-value pairs: KEY, NAME, ID, TYPE, STATUS, DESCRIPTION | -| ~~JSON output~~ (#392 removed) | `cfl space view confluence -o json` | Errors: invalid output format | | Non-existent space | `cfl space view NONEXISTENT` | Error: Space with key 'NONEXISTENT' not found | | View personal space | `cfl space view ~accountid` | Shows personal space details (if accessible) | | Alias: get | `cfl space get confluence` | Same output as `space view` | @@ -217,7 +209,6 @@ All cfl commands should work with both auth methods (no scope limitations for Co | Test Case | Command | Expected Result | |-----------|---------|-----------------| | Create global space | `cfl space create --key INTTEST --name "[Test] Integration" --description "Test space"` | Space created, shows KEY, NAME, URL | -| ~~Create with JSON output~~ (#392 removed) | `cfl space create --key INTTEST2 --name "[Test] Int2" -o json` | Errors: invalid output format | | Missing key flag | `cfl space create --name "Test"` | Error: required flag(s) "key" not set | | Missing name flag | `cfl space create --key TST` | Error: required flag(s) "name" not set | | Duplicate key | `cfl space create --key INTTEST --name "Duplicate"` (after creating INTTEST) | Error: API rejects duplicate key | @@ -229,7 +220,6 @@ All cfl commands should work with both auth methods (no scope limitations for Co | Update name | `cfl space update INTTEST --name "[Test] Updated Name"` | Shows updated key and name | | Update description | `cfl space update INTTEST --description "Updated description"` | Shows updated key and name | | Update both | `cfl space update INTTEST --name "[Test] Both" --description "Both updated"` | Both name and description changed | -| ~~JSON output~~ (#392 removed) | `cfl space update INTTEST --name "[Test] JSON" -o json` | Errors: invalid output format | | No flags provided | `cfl space update INTTEST` | Error: at least one of --name or --description required | | Non-existent space | `cfl space update NONEXISTENT --name "X"` | Error: not found | | Verify update | `cfl space view INTTEST` | Shows new name and description | @@ -241,7 +231,6 @@ All cfl commands should work with both auth methods (no scope limitations for Co | Delete with confirmation | `cfl space delete INTTEST` (type "y") | Space deleted after confirmation prompt | | Delete cancelled | `cfl space delete INTTEST` (type "n") | "Deletion cancelled" message | | Delete with --force | `cfl space delete INTTEST --force` | Space deleted without confirmation | -| ~~JSON output~~ (#392 removed) | `cfl space delete INTTEST --force -o json` | Errors: invalid output format | | Non-existent space | `cfl space delete NONEXISTENT --force` | Error: not found | ### Space CRUD End-to-End (sequential) @@ -253,7 +242,7 @@ All cfl commands should work with both auth methods (no scope limitations for Co | 3. Update name | `cfl space update INTTEST --name "[Test] Updated"` | Name updated | | 4. Verify update | `cfl space view INTTEST` | Shows new name | | 5. Update desc | `cfl space update INTTEST --description "New description"` | Description updated | -| 6. List includes it | `cfl space list \| grep INTTEST` | Space appears in list (was `-o json \| jq` pre-#392) | +| 6. List includes it | `cfl space list \| grep INTTEST` | Space appears in list | | 7. Delete | `cfl space delete INTTEST --force` | "Deleted space INTTEST" | | 8. Verify gone | `cfl space view INTTEST` | Error: not found | @@ -272,7 +261,6 @@ All cfl commands should work with both auth methods (no scope limitations for Co | Search by label | `cfl search --label test-label` | Content with specified label | | Combined filters | `cfl search "deploy" --space DEV --type page` | Filtered results | | Raw CQL | `cfl search --cql "type=page AND space=DEV"` | CQL executed directly | -| ~~JSON output~~ (#392 removed) | `cfl search "test" -o json` | Errors: invalid output format | | Plain output | `cfl search "test" -o plain` | Tab-separated values | | Limit results | `cfl search "test" --limit 5` | Max 5 results | | No results | `cfl search "xyznonexistent123"` | "No results found" message | @@ -534,7 +522,6 @@ Copies in the TEST space (originals from INT, CUS, PROD, PLAYBOOK): |-----------|---------|-----------------| | View ADF page (default) | `cfl page view ` | Shows markdown content (not "(No content)") | | View ADF page (ADF) | `cfl page view --body-format adf` | Shows exact ADF JSON | -| ~~View ADF page (JSON)~~ (#392 removed) | `cfl page view -o json` | Errors: invalid output format | | View ADF page (content-only) | `cfl page view --content-only` | Shows content without headers | | View legacy page (no regression) | `cfl page view ` | Shows markdown content via storage path | @@ -581,7 +568,6 @@ Copies in the TEST space (originals from INT, CUS, PROD, PLAYBOOK): | Format | Flag | Verified With | |--------|------|---------------| | Table (default) | (none) | Visual inspection | -| ~~JSON~~ (#392 removed) | `--output json` | errors at root | | Plain | `--output plain` | Tab-separated, scriptable | --- @@ -623,7 +609,6 @@ All cfl commands work with both auth methods (no scope restrictions for Confluen #### ADF Body Fallback (#150) - [ ] View ADF page with empty storage → content displayed via ADF fallback - [ ] View ADF page with `--body-format adf` → shows exact ADF JSON -- [ ] ~~View ADF page (JSON output)~~ (#392 removed) - [ ] Edit ADF page (title only) → ADF body preserved - [ ] Edit ADF page (new content) → submitted as ADF - [ ] View/edit legacy page → no regression (storage path used) @@ -649,15 +634,12 @@ All cfl commands work with both auth methods (no scope restrictions for Confluen - [ ] Full-text search returns results - [ ] Space filter works - [ ] Type filter works -- [ ] ~~JSON output is valid~~ (#392 removed; -o json errors at root) - [ ] Raw CQL works #### Space CRUD - [ ] View space (table output) -- [ ] ~~View space (JSON output)~~ (#392 removed) - [ ] View non-existent space (expect error) - [ ] Create space with key, name, description -- [ ] ~~Create space (JSON output)~~ (#392 removed) - [ ] Create duplicate key (expect error) - [ ] Update space name - [ ] Update space description @@ -716,7 +698,6 @@ All cfl commands work with both auth methods (no scope restrictions for Confluen #### ADF Body Fallback (#150) - [ ] View ADF page with empty storage → content displayed via ADF fallback - [ ] View ADF page with `--body-format adf` → shows exact ADF JSON -- [ ] ~~View ADF page (JSON output)~~ (#392 removed) - [ ] Edit ADF page (title only) → ADF body preserved - [ ] Edit ADF page (new content) → submitted as ADF - [ ] View/edit legacy page → no regression (storage path used) @@ -742,15 +723,12 @@ All cfl commands work with both auth methods (no scope restrictions for Confluen - [ ] Full-text search returns results - [ ] Space filter works - [ ] Type filter works -- [ ] ~~JSON output is valid~~ (#392 removed; -o json errors at root) - [ ] Raw CQL works #### Space CRUD - [ ] View space (table output) -- [ ] ~~View space (JSON output)~~ (#392 removed) - [ ] View non-existent space (expect error) - [ ] Create space with key, name, description -- [ ] ~~Create space (JSON output)~~ (#392 removed) - [ ] Create duplicate key (expect error) - [ ] Update space name - [ ] Update space description diff --git a/tools/cfl/internal/cmd/attachment/list_test.go b/tools/cfl/internal/cmd/attachment/list_test.go index dd309280..0a5566ed 100644 --- a/tools/cfl/internal/cmd/attachment/list_test.go +++ b/tools/cfl/internal/cmd/attachment/list_test.go @@ -130,8 +130,7 @@ func TestRunList_Empty(t *testing.T) { err := runList(context.Background(), opts) testutil.RequireNoError(t, err) - // The empty-results banner used to be suppressed under -o json; #392 - // removed that skip, so the banner now always prints to stderr. + // The empty-results banner always prints to stderr. testutil.Contains(t, rootOpts.Stderr.(*bytes.Buffer).String(), "No attachments found.") } diff --git a/tools/cfl/test-plan-writes.md b/tools/cfl/test-plan-writes.md index f96a0b1b..b4f162e4 100644 --- a/tools/cfl/test-plan-writes.md +++ b/tools/cfl/test-plan-writes.md @@ -6,8 +6,6 @@ The documentation (readme.md, cfl-intro.md) makes numerous claims about write op This document inventories all untested assertions and provides comprehensive test cases. -> **#392 update:** Rows that exercise `-o json` / `--output json` on resource commands are obsolete — the resource JSON surface has been removed. They now error at the root. Skip those rows; the `cfl page create` ID-capture pattern (test 4.2.2) should be re-run by parsing the `ID:` key-value line from the default text output instead. - --- ## Untested Claims Inventory @@ -177,7 +175,6 @@ This document inventories all untested assertions and provides comprehensive tes | # | Test Case | Command | Expected | Priority | |---|-----------|---------|----------|----------| | 1.8.1 | Default output | `cfl page create -s SPACE -t "Test" -f test.md` | Success message with ID, URL | HIGH | -| 1.8.2 | ~~JSON output~~ (#392 removed) | `cfl page create -s SPACE -t "Test" -f test.md -o json` | Errors: invalid output format | OBSOLETE | | 1.8.3 | Plain output | `cfl page create -s SPACE -t "Test" -f test.md -o plain` | Tab-separated | LOW | --- @@ -216,7 +213,6 @@ This document inventories all untested assertions and provides comprehensive tes |---|-----------|---------|----------|----------| | 2.3.1 | List page with attachments | `cfl attachment list -p PAGE_ID` | Table with ID, name, type, size | HIGH | | 2.3.2 | List page without attachments | `cfl attachment list -p PAGE_NO_ATT` | "No attachments" message | MEDIUM | -| 2.3.3 | ~~JSON output~~ (#392 removed) | `cfl attachment list -p PAGE_ID -o json` | Errors: invalid output format | OBSOLETE | --- @@ -269,7 +265,7 @@ This document inventories all untested assertions and provides comprehensive tes | # | Test Case | Command | Expected | Priority | |---|-----------|---------|----------|----------| | 4.2.1 | Pipe file content | `cat notes.md \| cfl page create -s SPACE -t "Test"` | Page created | HIGH | -| 4.2.2 | Capture created ID | `cfl page create -s SPACE -t "Test" -f x.md \| awk -F': ' '/^ID:/ {print $2; exit}'` | Extracts page ID (was `-o json \| jq -r .id` pre-#392) | HIGH | +| 4.2.2 | Capture created ID | `cfl page create -s SPACE -t "Test" -f x.md \| awk -F': ' '/^ID:/ {print $2; exit}'` | Extracts page ID | HIGH | | 4.2.3 | Script: create many pages | Loop creating 10 pages | All succeed | MEDIUM | ---