Skip to content

tsk-ourbp6 [OPEN] Rebase PR #200 (feat/version-capabilities) onto cu - #213

Merged
jaylfc merged 3 commits into
masterfrom
exec/tsk-ourbp6
Jul 27, 2026
Merged

tsk-ourbp6 [OPEN] Rebase PR #200 (feat/version-capabilities) onto cu#213
jaylfc merged 3 commits into
masterfrom
exec/tsk-ourbp6

Conversation

@jaylfc

@jaylfc jaylfc commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Autonomous build of board card tsk-ourbp6.

Files:
README.md | 46 +-
docs/collections.md | 33 +
docs/serve-service.md | 23 +-
taosmd/capabilities.py | 390 +++
taosmd/http_server.py | 38 +-
tests/test_version_capabilities.py | 388 +++
uv.lock | 4933 ++++++++++++++++++++++++++++++++++++
8 files changed, 5841 insertions(+), 13 deletions(-)

Summary by CodeRabbit

  • New Features

    • Added a public GET /version endpoint with build metadata and supported capability identifiers.
    • Expanded GET /health responses to include capabilities.
    • Added capability discovery for collections, grants, tasks, A2A, and temporal contracts.
    • Collections Phase 1 documentation now covers supported APIs, configuration, indexing, provenance, deduplication, and access enforcement.
  • Documentation

    • Clarified bearer-token requirements and public endpoints.
    • Added guidance for reliably detecting server capabilities without probing unsupported routes.

jaylfc added 2 commits July 27, 2026 02:19
Neither a status code nor a version number could answer "does this box
actually speak collections". taosmd serve renders the dashboard SPA on
unknown non-API paths, so GET /collections returns 200 text/html on a
build with no collections code, and checking for a 200 is a check that
always passes. Semver does not close the gap either: features land
between bumps, and a production box ran a month-stale build unnoticed
even though GET /health already reported a version.

Add GET /version returning version, commit, commit_source, built_at,
built_at_source, and capabilities. Add the same capabilities list to
GET /health alongside its existing status and version keys, which are
unchanged (taOS and the dashboard consume both). Both endpoints are
public by design and join /health in _PUBLIC_PATHS, so monitoring and
drift probes keep working on a token-secured box. They expose build
identity and capability identifiers only.

Capabilities are stable contract identifiers with an explicit version
suffix, not feature names: a breaking change to a wire contract becomes
collections.v2, so a client pinned to collections.v1 sees the capability
disappear rather than collections quietly meaning something new.

The list is derived by probing the running build. Each identifier is
declared in taosmd/capabilities.py next to the module and symbols that
implement it and is advertised only if they resolve, so deleting the
code deletes the claim. A divergence test asserts every declared
capability's routes exist in the real dispatcher.

The commit sha is resolved once and cached, never per request and never
by shelling out: git rev-parse in a request path can block on a lock or
a slow filesystem. The plumbing is read straight from the filesystem
(.git/HEAD to loose ref or packed-refs, including the gitdir:
indirection used by worktrees), with an optional packaged
taosmd/_build_info.py stamp taking precedence for wheel and container
builds. Every step degrades to null rather than raising.
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds runtime capability and build-identity reporting, exposes public /version and expanded /health responses, updates token gating, and adds tests and documentation for capability discovery, metadata fallback, and endpoint contracts.

Changes

Capability Discovery and Public Version Reporting

Layer / File(s) Summary
Capability probes and build identity
taosmd/capabilities.py
Defines versioned capability probes, resolves supported symbols at runtime, caches results, resolves commit and build timestamp metadata, and assembles the /version payload.
HTTP endpoint integration
taosmd/http_server.py
Adds public GET /version, includes capabilities in /health, exempts /version from bearer-token gating, and updates endpoint startup output.
Contract validation and discovery documentation
tests/test_version_capabilities.py, README.md, docs/collections.md, docs/serve-service.md, CHANGELOG.md
Validates capability contracts, metadata resolution, caching, endpoint schemas, public access, protected data-plane routes, and documents capability-based discovery and the related changelog entries.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • jaylfc/taosmd#194: Both changes modify bearer-token routing and endpoint authorization in taosmd/http_server.py.
  • jaylfc/taosmd#200: Directly overlaps the capability module, public endpoint contracts, and capability-focused tests.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title describes a rebase operation, not the version/capabilities feature added in this PR. Rename it to summarize the actual change, e.g. "Add /version and capability reporting".
Docstring Coverage ⚠️ Warning Docstring coverage is 70.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch exec/tsk-ourbp6

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gitar-bot

gitar-bot Bot commented Jul 27, 2026

Copy link
Copy Markdown

Gitar is working

Gitar

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

feat(api): Add /version endpoint with runtime capability advertisement

✨ Enhancement 📝 Documentation 🧪 Tests ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Add public GET /version with build identity and runtime-derived capability list.
• Extend GET /health to include capabilities without breaking existing status/version contract.
• Document capability discovery and add tests preventing capability/route drift.
Diagram

graph TD
  Client["Client / monitor"] --> HTTP["taosmd/http_server.py"] --> Endpoints["/health + /version"] --> Caps["taosmd/capabilities.py"]
  Caps --> Probes["Capability probes"]
  Caps --> Git[(".git plumbing")]
  Caps --> Stamp[("_build_info.py / dist-info")]
  Probes --> Service["taosmd/service"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Build-time generated capability manifest
  • ➕ Zero runtime imports/probing; simplest request path
  • ➕ Can be reviewed/validated during CI build
  • ➖ Easy to drift from the running code if packaging steps are skipped/misconfigured
  • ➖ Harder to support source checkouts vs wheels uniformly without extra tooling
2. Router-introspection based capabilities (derive from dispatcher only)
  • ➕ Directly reflects exposed HTTP surface (no need for route_markers table)
  • ➕ Less coupling to internal symbol names
  • ➖ Does not prove backing implementation exists if routes are present but broken
  • ➖ More complex with hand-written dispatchers vs framework routers
3. Explicit config flag for supported contracts
  • ➕ No import/probe overhead; fully operator-controlled
  • ➕ Can gate experimental features intentionally
  • ➖ Risk of stale/incorrect configuration (the core problem this PR is avoiding)
  • ➖ Adds operational burden and another drift vector

Recommendation: Keep the PR’s approach: runtime probing provides the strongest anti-drift guarantee (code absence removes the claim), while caching keeps the endpoint cheap. The added divergence test (route_markers vs dispatcher text) is a pragmatic safeguard given the hand-written dispatcher, and best-effort git/build identity resolution avoids introducing brittle request-path dependencies.

Files changed (8) +5841 / -13

Enhancement (2) +421 / -7
capabilities.pyImplement capability probes and build identity resolution for /version +390/-0

Implement capability probes and build identity resolution for /version

• Introduces a CapabilityProbe table mapping stable contract identifiers to required module symbols and route markers, and exposes cached capability derivation. Adds best-effort build identity resolution (commit + built_at) preferring a packaged build stamp and otherwise reading git metadata/dist-info timestamps, with strict non-raising, non-shelling-out behavior.

taosmd/capabilities.py

http_server.pyExpose GET /version and add capabilities to /health +31/-7

Expose GET /version and add capabilities to /health

• Adds /version endpoint returning version/build identity/capabilities and augments /health to include the same capabilities list while preserving existing keys. Marks /version as always-public in _PUBLIC_PATHS and updates inline endpoint documentation and startup logging.

taosmd/http_server.py

Tests (1) +388 / -0
test_version_capabilities.pyAdd tests for capability contract, drift prevention, and endpoint behavior +388/-0

Add tests for capability contract, drift prevention, and endpoint behavior

• Adds an end-to-end test suite validating capability format (.vN), copy-on-read caching, dropping claims when symbols are missing, and preventing probe declarations from diverging from the dispatcher. Verifies /version and /health shapes, that neither leaks sensitive data, and that both endpoints remain public even when a server_token gates the rest of the data plane.

tests/test_version_capabilities.py

Documentation (4) +99 / -6
CHANGELOG.mdDocument /version endpoint and capability contract rationale +2/-1

Document /version endpoint and capability contract rationale

• Adds an Unreleased changelog entry describing the new /version endpoint, the capability identifier contract (.vN), and the best-effort build identity fields. Also documents the motivation (status-code probing is unsafe due to SPA fallback) and the no-shell-out git resolution approach.

CHANGELOG.md

README.mdAdd capability discovery docs and update API table +44/-2

Add capability discovery docs and update API table

• Updates token/public endpoint documentation to include GET /version. Extends the API table to show capabilities on /health and the new /version response shape, and adds a dedicated section explaining capability membership checks and field meanings.

README.md

collections.mdWarn against status-code probing; direct users to /version +33/-0

Warn against status-code probing; direct users to /version

• Adds guidance to verify collections support via GET /version and capability membership checks instead of probing /collections (which can return 200 text/html on unsupported builds). Clarifies how collections.v1 and grants.v1 map to the collections surface.

docs/collections.md

serve-service.mdDocument /version as public endpoint and show usage +20/-3

Document /version as public endpoint and show usage

• Updates service docs to note that /version stays public alongside /health and the UI even when bearer auth is enabled. Adds example calls and explains why capability membership is the correct check.

docs/serve-service.md

Other (1) +4933 / -0
uv.lockAdd/update uv lockfile for reproducible dependency resolution +4933/-0

Add/update uv lockfile for reproducible dependency resolution

• Introduces a uv.lock file pinning the Python dependency set for reproducible installs and CI parity. Large lockfile-only change; no runtime behavior beyond dependency resolution determinism.

uv.lock

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 13 rules

Grey Divider


Remediation recommended

1. Unvalidated build stamp 🐞 Bug ≡ Correctness
Description
taosmd.capabilities._build_stamp() accepts any non-empty COMMIT/BUILT_AT strings from
taosmd/_build_info.py, and /version will publish them as-is. This can violate the documented
contract (commit must be a 40-hex sha; built_at must be ISO 8601 UTC) and break
clients/monitoring that rely on those shapes.
Code

taosmd/capabilities.py[R231-250]

+def _build_stamp() -> dict | None:
+    """Optional build-time stamp written by a packaging step.
+
+    A wheel or container build may drop a ``taosmd/_build_info.py`` exporting
+    ``COMMIT`` and/or ``BUILT_AT`` (ISO 8601). It is absent from a plain source
+    checkout, which is why the git reader below exists.
+    """
+    try:
+        module = importlib.import_module("taosmd._build_info")
+    except Exception:  # noqa: BLE001 - unstamped build is the normal case
+        return None
+    commit = getattr(module, "COMMIT", None)
+    built_at = getattr(module, "BUILT_AT", None)
+    if not isinstance(commit, str) or not commit.strip():
+        commit = None
+    if not isinstance(built_at, str) or not built_at.strip():
+        built_at = None
+    if commit is None and built_at is None:
+        return None
+    return {"commit": commit, "built_at": built_at}
Relevance

⭐⭐⭐ High

Team often accepts adding validation/invariant checks to prevent contract drift; low-risk
correctness fix.

PR-#201

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The README documents strict formats for commit and built_at, but _build_stamp() only checks
for non-empty strings and returns them unchanged, so a malformed packaged _build_info.py would be
exposed via /version. The git-derived path does validate via _looks_like_sha(), highlighting
that validation is missing specifically for the stamp path.

README.md[753-762]
taosmd/capabilities.py[231-250]
taosmd/capabilities.py[303-333]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`_build_stamp()` currently treats any non-empty `COMMIT` and `BUILT_AT` values as valid and returns them unchanged. Because `resolve_commit()` / `_resolve_built_at()` prefer the build stamp, `/version` can return malformed values (e.g., short sha, whitespace-padded sha, non-ISO timestamp), violating the public contract documented in the README.

## Issue Context
Git-derived commits are already validated via `_looks_like_sha()`, and install-derived `built_at` is formatted as `...Z`. Only the build-stamp path lacks validation/normalization.

## Fix Focus Areas
- taosmd/capabilities.py[231-250]
- taosmd/capabilities.py[307-333]
- taosmd/capabilities.py[335-356]

## Suggested fix
1. In `_build_stamp()`:
  - `commit = commit.strip()` and validate with `_looks_like_sha(commit)`; otherwise set `commit = None`.
  - `built_at = built_at.strip()` and strictly parse/validate ISO-8601; require UTC (either `Z` or `+00:00`), then normalize to `YYYY-MM-DDTHH:MM:SSZ`. If invalid, set `built_at = None`.
2. Keep the existing fallback behavior: if stamp values are invalid/None, fall back to git plumbing and/or install mtime.
3. Add/extend tests to cover malformed stamp values (short sha, non-hex, whitespace, non-UTC timestamps) and assert they become `null` rather than being published.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread taosmd/capabilities.py
Comment on lines +231 to +250
def _build_stamp() -> dict | None:
"""Optional build-time stamp written by a packaging step.

A wheel or container build may drop a ``taosmd/_build_info.py`` exporting
``COMMIT`` and/or ``BUILT_AT`` (ISO 8601). It is absent from a plain source
checkout, which is why the git reader below exists.
"""
try:
module = importlib.import_module("taosmd._build_info")
except Exception: # noqa: BLE001 - unstamped build is the normal case
return None
commit = getattr(module, "COMMIT", None)
built_at = getattr(module, "BUILT_AT", None)
if not isinstance(commit, str) or not commit.strip():
commit = None
if not isinstance(built_at, str) or not built_at.strip():
built_at = None
if commit is None and built_at is None:
return None
return {"commit": commit, "built_at": built_at}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

1. Unvalidated build stamp 🐞 Bug ≡ Correctness

taosmd.capabilities._build_stamp() accepts any non-empty COMMIT/BUILT_AT strings from
taosmd/_build_info.py, and /version will publish them as-is. This can violate the documented
contract (commit must be a 40-hex sha; built_at must be ISO 8601 UTC) and break
clients/monitoring that rely on those shapes.
Agent Prompt
## Issue description
`_build_stamp()` currently treats any non-empty `COMMIT` and `BUILT_AT` values as valid and returns them unchanged. Because `resolve_commit()` / `_resolve_built_at()` prefer the build stamp, `/version` can return malformed values (e.g., short sha, whitespace-padded sha, non-ISO timestamp), violating the public contract documented in the README.

## Issue Context
Git-derived commits are already validated via `_looks_like_sha()`, and install-derived `built_at` is formatted as `...Z`. Only the build-stamp path lacks validation/normalization.

## Fix Focus Areas
- taosmd/capabilities.py[231-250]
- taosmd/capabilities.py[307-333]
- taosmd/capabilities.py[335-356]

## Suggested fix
1. In `_build_stamp()`:
   - `commit = commit.strip()` and validate with `_looks_like_sha(commit)`; otherwise set `commit = None`.
   - `built_at = built_at.strip()` and strictly parse/validate ISO-8601; require UTC (either `Z` or `+00:00`), then normalize to `YYYY-MM-DDTHH:MM:SSZ`. If invalid, set `built_at = None`.
2. Keep the existing fallback behavior: if stamp values are invalid/None, fall back to git plumbing and/or install mtime.
3. Add/extend tests to cover malformed stamp values (short sha, non-hex, whitespace, non-UTC timestamps) and assert they become `null` rather than being published.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@taosmd/http_server.py`:
- Line 624: Update the `_check_token` docstring to mention `/version` alongside
the existing public health and UI paths, matching the `_PUBLIC_PATHS` allowlist
without changing authentication behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9ecd77bc-a5ca-4358-8a70-0cc50b0dd1fc

📥 Commits

Reviewing files that changed from the base of the PR and between 3b97698 and 6ddd6a6.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • CHANGELOG.md
  • README.md
  • docs/collections.md
  • docs/serve-service.md
  • taosmd/capabilities.py
  • taosmd/http_server.py
  • tests/test_version_capabilities.py

Comment thread taosmd/http_server.py

# Paths that are always public regardless of the token setting.
_PUBLIC_PATHS = frozenset({"/", "/ui", "/health"})
_PUBLIC_PATHS = frozenset({"/", "/ui", "/health", "/version"})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

_check_token docstring now stale.

_PUBLIC_PATHS gains "/version" here, but the nearby _check_token docstring ("Public paths (health, UI) are always authorised.") still only names health/UI, not version. Worth a one-line update so the docstring doesn't mislead a future reader of the auth gate.

📝 Suggested docstring tweak
-            Public paths (health, UI) are always authorised.
+            Public paths (health, version, UI) are always authorised.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@taosmd/http_server.py` at line 624, Update the `_check_token` docstring to
mention `/version` alongside the existing public health and UI paths, matching
the `_PUBLIC_PATHS` allowlist without changing authentication behavior.

@jaylfc

jaylfc commented Jul 27, 2026

Copy link
Copy Markdown
Owner Author

Lead review with verification evidence (the PR body omits it):

Content verified as the approved #200 feature, correctly rebased. taosmd/capabilities.py and tests/test_version_capabilities.py are byte-identical to the reviewed feat/version-capabilities content; the http_server.py hunks are exactly the /version endpoint + /health capabilities addition with the docstring-table documentation. Suite in the same env as the master baseline: 1196 passed / 9 failed / 5 skipped, failing set byte-identical (+21, all the version-capabilities tests).

Process note: the card said force-push feat/version-capabilities so #200 updates; the lane opened this new PR instead. Accepting it as the vehicle under the one-PR-per-task retry rule (predecessor closes), because the content is right and the review context carries over via this comment: #200 had CodeRabbit's completed pass and the Jay+lead walkthrough approval on 2026-07-26. #200 will be closed with a pointer here when this merges — not before.

One blocker, same as #212: remove uv.lock (+4,933 lines, untracked on master by design, out of card scope). This is now systemic — two lanes committed it — so it is also flagged to the pipeline owner. Fix-forward card filed; merge follows immediately after.

taosmd does not track a lockfile. uv sync produced one during the run and it
was staged as a side effect, adding 4933 lines to an unrelated change and
giving a repo that had not adopted a committed lockfile one by accident.

Whether taosmd should track a lockfile is a deliberate decision for its
maintainer, not a side effect of an envelope change.

The executor now scrubs generated artifacts a branch adds that the base does
not track, so this cannot recur.
@jaylfc
jaylfc merged commit 5b024fe into master Jul 27, 2026
1 of 2 checks passed
jaylfc added a commit that referenced this pull request Aug 17, 2026
… never exercised their own rule (#311)

Replaces the all-or-nothing #212 revert with eight per-rule reverts, one per
validation rule, so a missing sub-rule can be seen rather than masked by the
other seven. That granularity paid: R1 and R5 were false negatives. The test
inputs used the string "not a list", which has len 10 and so tripped the
max-refs guard, and which iterates into characters and so tripped the
item-type guard, before the isinstance check was ever reached. Disabling the
is-a-list rule left both tests green. The inputs are now non-iterable (42),
and the same perturbation turns both red.

Relabels the report TARGETED/UNRELATED, reserving DECORATIVE for tautologies
(none found), which removes the contradiction where one test was REAL in one
table and DECORATIVE in another. Splits row 13 out: its status assertion is
duplicated at the service layer, so only its message assertion is
load-bearing. Keeps the test_capability_declarations_do_not_diverge
retraction prominent.

Reviewer's note on provenance: the PR body's file table and its reported
suite count of 1401 belong to a different tree. They credit this PR with
scripts/normalise_handle_gate.py, scripts/check_deleted_symbols.py,
tests/test_deleted_symbols.py, tests/test_normalise_handle_gate.py and a
changelog entry for card tsk-vcda2i, all of which are #306's and #308's
already-merged work. This change is two files, 308 insertions, and the suite
on the trial merge is 1435 passed / 12 skipped.

Card tsk-24ybw5. Review: #311 (comment)
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