Skip to content

Scan every Confluence space type, not just global (#191) - #208

Merged
icebergai-review-bot[bot] merged 1 commit into
mainfrom
claude/codebase-review-cleanup-ovlli4
Aug 20, 2026
Merged

Scan every Confluence space type, not just global (#191)#208
icebergai-review-bot[bot] merged 1 commit into
mainfrom
claude/codebase-review-cleanup-ovlli4

Conversation

@richardmhope

Copy link
Copy Markdown
Contributor

Closes #191. The last of the codebase-review issues.

The taxonomy, established

The issue said this needed verification against a real Cloud site. It didn't — every atlassian.com host is blocked by this environment's egress policy, but the spec reaches us another way. confluence.js v3.2.0 (README: "derived from Atlassian's OpenAPI spec") encodes the GET /spaces query parameter with Atlassian's own docstrings intact:

/** Filter the results to spaces based on their type. */
type: openEnum([
    'global', 'collaboration', 'knowledge_base', 'personal',
    'system', 'onboarding', 'xflow_sample_space',
]).optional(),

Corroborated by a web search for the distinctive string "xflow_sample_space" returning Atlassian's own space API docs as the top hit, and by CONFCLOUD-80579 "Add Collaboration and Knowledge_base Space types".

Seven types, and the filter takes one value — not a list. So type=global is not a narrowing, it is an omission of five, and there was never a server-side way to express "everything except personal".

Why this is worse than the issue estimated

Two of the five dropped types are collaboration and knowledge_basethe first two options Confluence's own space-creation flow offers. On any site created in recent years this isn't an edge case, it's most of the site. A knowledge base full of credentials was never read, and the scan completed looking clean over a scope the operator believed was covered.

The fix

Discovery lists every type and decides for itself:

  • A personal space is excluded unless opted in — compared case-insensitively. The spec documents lower_case; there's a report that the v2 API returns UPPER_CASE.`` Trusting the documented spelling would scan every user's drafts on a site that asked not to — the same failure from the other side, so it's tested with three spellings.
  • A space named explicitly in spaces is scanned whatever its type. Naming it is the deliberate decision the flag otherwise stands in for, and the alternative was reporting a space that plainly exists as not found.
  • An unrecognised type is scanned, and logged. A type Atlassian adds after this release must not become content nobody looks at — excluding the unknown reopens the same hole from the other direction. But "is the new type personal-like?" is a question an operator should answer before a coverage report raises it for them, so confluence_unknown_space_types names it.

Accepted cost: personal spaces dominate the space count on a large site, so discovery now pages past them to discard each one — a few extra metadata requests once per scan. Against silently missing every space of an unnamed type, that's the right side of the trade, and the docstring says so.

Why the suite didn't catch it

confluence_server.py modelled only global and personal. It models the rest now, with a comment saying that's why the fixture exists.

Nine new tests; seven fail against the previous code (verified by stashing the connector and re-running). The two that pass either way guard the behaviour being preserved — personal spaces still excluded, and now case-insensitively.

make check green: ruff, mypy (285 files), docs check, 2035 passed / 2 skipped.

Operator action

Re-scan any Confluence source. Findings in non-global spaces have never been seen, so this is new coverage rather than a correction — until that scan runs, the source's history describes only part of the site. Noted in the CHANGELOG.


Generated by Claude Code

Excluding personal spaces was implemented as asking the v2 API for
`type=global`. That reads as "everything except personal" and is not. The
enum is `global`, `collaboration`, `knowledge_base`, `personal`, `system`,
`onboarding` and `xflow_sample_space`, and the filter takes a single value
rather than a list — so there is no server-side way to express the intent, and
the implementation dropped five of the seven types.

Two of those five are `collaboration` and `knowledge_base`: the first two
options Confluence's own space-creation flow offers. On any site created in
recent years this is not an edge case, it is most of the site. A knowledge base
full of credentials was never read, and the scan completed looking clean over a
scope the operator believed was covered — the silent empty scan this codebase
treats as the dangerous failure, arrived at through a filter that looked like a
narrowing rather than an omission.

Discovery now lists every type and decides for itself:

* a personal space is excluded unless opted in, compared case-insensitively.
  The spec documents lower_case and the API has been reported returning
  UPPER_CASE; trusting the documented spelling would scan every user's drafts
  on a site that asked not to, which is the same failure from the other side.
* a space named explicitly in `spaces` is scanned whatever its type. Naming it
  is the deliberate decision the flag otherwise stands in for, and refusing
  would report a space that plainly exists as "not found".
* a type this build does not recognise is **scanned**, and logged. A type
  Atlassian adds after this release must not become content nobody looks at —
  excluding the unknown would reopen the same hole from the other direction —
  but "is this new type personal-like?" is a question an operator should answer
  before a coverage report raises it for them.

The cost is real and accepted: personal spaces dominate the space count on a
large site, so discovery pages past them to discard each one. That is a few
extra metadata requests once per scan, against silently missing every space of
a type the filter did not name.

The fixture modelled only `global` and `personal`, which is why the whole suite
passed against the defect. It models the rest now, and seven of the nine new
tests fail against the previous code.

Refs ADR 0009.

Claude-Session: https://claude.ai/code/session_012sohE85sRDt6t2w3936rGJ

Co-authored-by: Claude <noreply@anthropic.com>

@icebergai-review-bot icebergai-review-bot 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.

Verdict

APPROVE

Completed bounded review across 1 immutable scope(s). No actionable defects found in the supplied change.

Scope health

Convergence: healthy. Review mode: initial.
Recommended action: CONTINUE_INCREMENTAL.

  • No escalation signals.

Prior findings

Finding Status
No prior finding state

New findings

No new findings.

Fix-induced regressions

  • None evidenced.

Uncertainty

  • No material uncertainty recorded.

Validation

  • Reviewed the supplied immutable patch and its added Confluence discovery coverage.

Residual risks

  • None identified.

@icebergai-review-bot
icebergai-review-bot Bot merged commit 833a33f into main Aug 20, 2026
6 checks passed
@icebergai-review-bot
icebergai-review-bot Bot deleted the claude/codebase-review-cleanup-ovlli4 branch August 20, 2026 02:49
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.

Confluence "exclude personal spaces" is implemented as type=global, which also excludes collaboration/knowledge_base spaces

2 participants