Skip to content

Require explicit api_root for an index API#478

Draft
consideRatio wants to merge 1 commit into
mainfrom
feat/require-api-root
Draft

Require explicit api_root for an index API#478
consideRatio wants to merge 1 commit into
mainfrom
feat/require-api-root

Conversation

@consideRatio

Copy link
Copy Markdown
Collaborator

Summary

Stop defaulting api_root to the discovery root. An index now exposes an API only when its discovery document (sysand-index-config.json) advertises api_root explicitly. Absent that, the index is read-only, regardless of whether its discovery root is a plain URL or a URL template.

This makes the invariant clean and unambiguous:

"the index has an API" == "the discovery document advertises api_root"

Previously a plain-URL index implicitly gained an api_root equal to its discovery root, so it looked like it had an API surface even when it was a static-file mirror. That ambiguity is exactly what makes it hard, elsewhere in the client, to tell "I failed to reach the API" apart from "there is no API". Removing the implicit default resolves it at the source.

Why now

This is the decoupled prerequisite for the credential-storage work (#453 / #437): login validation only wants to probe an API surface when one genuinely exists. With this landed, "advertises api_root" becomes the single reliable signal for "has an API", and the credential-storage branch can rely on it.

Behavior changes

  • Reads: unaffected. Index reads use index_root, which still defaults to the discovery root.
  • Publish: publishing to an index that advertises no api_root now fails early with does not advertise a publish endpoint instead of composing an upload request against the discovery root. (This message already existed for templated indexes; it is now the general case.)
  • Pasting the upload URL as --index: now yields the same "no publish endpoint" refusal (404 discovery → no api_root) rather than reaching api_root shape validation. Shape validation still guards an advertised api_root that points at the upload endpoint, and keeps its unit coverage.

BREAKING CHANGE: a plain-URL index that previously accepted uploads at the discovery root must now advertise api_root in sysand-index-config.json.

Spec

design/index-protocol.md and design/index-api-protocol.md updated: api_root has no default; absence means no API / read-only.

Tests

  • New: discovery_absent_config_yields_no_api_root, discovery_config_without_api_root_yields_no_api_root lock the new contract (404 config and {} config both leave api_root unset).
  • Repurposed publish_rejects_upload_endpoint_index_url to assert the new bail path.
  • Full sysand-core --all-features lib suite (352) and the entire sysand CLI integration suite pass; clippy clean across core + cli all-features.

🤖 Generated with Claude Code

Stop defaulting `api_root` to the discovery root. An index now exposes
an API only when its discovery document advertises `api_root`
explicitly; absent that, the index is read-only regardless of whether
its discovery root is a plain URL or a URL template.

This makes "the index has an API" mean exactly "the discovery document
advertises api_root", removing the ambiguity where a plain-URL index
looked like it had an API surface. Reads are unaffected (they use
index_root, which still defaults to the discovery root). Publishing to
an index that advertises no api_root now fails early with a clear
"does not advertise a publish endpoint" message instead of composing a
request against the discovery root.

BREAKING CHANGE: a plain-URL index that previously accepted uploads at
the discovery root must now advertise `api_root` in
sysand-index-config.json.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfyrkJkeo3mRngVoppJjUN
Signed-off-by: Erik Sundell <erik.sundell+2025@sensmetry.com>
@consideRatio
consideRatio force-pushed the feat/require-api-root branch from 53e62f1 to f9ef3ae Compare July 24, 2026 16:43
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