docs/RELEASE_NOTES_v0.2.0.en.md
Rama main · réplica de lectura del repositorio original.
# BailingHub v0.2.0: Tool Catalog Access Protection and Active Verification
`v0.2.0` turns URL tool-catalog access from an implicit convention into an explicit, verifiable governance control. Operators must state whether a catalog requires signed access or is intentionally public. The console reports configured intent separately from observed evidence instead of assuming that sending a signature proves the endpoint is protected.
This release governs who may download a tool catalog. Tool execution keeps the existing signatures, trusted subject, route allowlist, risk approval, idempotency, and final business authorization. ACC and the Client API are unchanged.
## User-visible results
- New URL providers default to **Signed protection (recommended)**. Operators choose **Public allowed** only when they intentionally accept exposing paths, parameters, scopes, and risk declarations to anyone who can reach the URL. Saving public access requires a second confirmation.
- The provider list shows the expected policy and the latest observed result independently, including signed, unsigned, and invalid-signature HTTP evidence.
- Signed mode is `protected` only when the valid signed request returns 2xx and the unsigned plus invalid-signature requests each return 401, 403, or 404.
- A negative request returning 2xx is `public`. Redirects, 429, 5xx, network errors, and other insufficient evidence are `inconclusive`. Both cases reject the candidate refresh and preserve the previous usable catalog.
- Public mode sends only an unsigned request and never silently retries with a signature.
## Two access policies
| Policy | Use case | Hub refresh behavior | Business-side requirement |
|---|---|---|---|
| `signed_required` | Default; the catalog must not be anonymous | Read with a valid signature, then run unsigned and invalid-signature probes | Verify the same provider secret used for tool calls; reject negative probes with 401/403/404; prevent protected-response caching |
| `public_allowed` | Intentional public catalog discovery | Send only an unsigned request | Anonymous GET may return the catalog; tool calls still require independent signatures and authorization |
The catalog policy does not replace business authorization. Even with a public catalog, actual tool requests must still validate `X-Bailing-Signature`, `X-Bailing-On-Behalf-Of`, task identity, and business permissions under the existing protocol.
## Active probes and cache safety
- Each request has a 10-second bound. The two negative probes run concurrently, so their worst-case waits do not add up to 20 seconds.
- The successful primary response is limited to 5 MiB using both `Content-Length` and actual streamed bytes.
- Formal policies do not follow redirects, preventing evidence from being attributed to the wrong target after a redirect.
- Exposure or inconclusive results persist probe evidence and sanitized audit events, while full `spec_url` values are excluded from alert notifications.
- The cached catalog is replaced only after both policy verification and catalog parsing succeed. Every failure preserves the old cache.
## Upgrading existing providers
Migration `053_tool_spec_access_policy.sql` adds nullable policy and latest-probe columns to `bz_tool_providers`. The normal upgrade sequence remains:
```bash
npm run db:init
# then restart BailingHub
```
Existing URL providers are not guessed to be public or protected:
- their cached catalogs remain unchanged and refresh keeps the previous signed-read behavior;
- the console labels them **Pending confirmation (historical configuration)** and preselects neither real policy;
- the internal `legacy_unverified` compatibility marker is read-only, absent from the public Schema, and rejected as a create or update value;
- disabling a provider or changing descriptive, governance, retrieval, and other non-catalog fields does not force a policy choice;
- changing the catalog URL, secret, auto-refresh, re-enabling, or another action that changes catalog reads first requires a formal policy;
- when the latest probe already proves protection, the console can adopt **Signed protection** with one click, while the operator still confirms the decision.
After confirmation, the database stores only `signed_required` or `public_allowed`. The internal historical marker is normalized to `NULL` during a later normal save or refresh, with no additional data-cleanup migration.
## PHP and PHP7 SDKs
PHP and PHP7 `SpecServer` add:
- `handlePublic()` for an explicit public catalog response;
- `respondPublic()` for an explicit bare-PHP public response;
- `responseHeaders()` for framework integrations;
- automatic `Cache-Control: private, no-store` on protected `respond($spec, $secret)` responses.
The older `handle(..., null)` and `respond($spec, null)` public forms remain compatible. New code should prefer the explicit `Public` helpers so public exposure is not hidden inside a `null` argument.
## Compatibility and boundaries
- This is an additive minor upgrade. The new database columns are nullable, and older code ignores them.
- ACC, the Client API version, executor protocol, tool-call signatures, approval semantics, idempotency rules, and final business authorization are unchanged.
- A new URL provider that omits the policy safely defaults to `signed_required`. Explicitly submitting the internal historical marker is rejected.
- Custom provider repositories may continue using the existing `upsert` path. The narrow probe-update method is an optional extension point.
- An application rollback should keep migration 053 and its ledger entry. Restore a full pre-upgrade database snapshot only together with the old application; do not drop the columns or delete the ledger entry independently.
## Validation
```bash
npm run release:check
npm run e2e:console
```
Focused coverage includes:
- request behavior and fail-closed handling for both formal policies;
- signed, unsigned, and invalid-signature status classification;
- timeout, response-size, and redirect boundaries;
- old-cache preservation, probe persistence, and alert sanitization;
- historical records remaining unguessed and requiring confirmation before catalog-sensitive changes;
- second confirmation for public mode and one-click adoption for protected historical providers;
- Schema, API, database repository, and PHP/PHP7 SDK compatibility.
## Related documentation
- [Compatibility and upgrades](COMPATIBILITY.en.md#url-tool-catalog-access-policy-upgrade)
- [Runtime contract](CONTRACT.en.md)
- [Integration guide](INTEGRATION.en.md#publish-tools)
- [Tool governance](TOOLS.en.md)
- [SDK guide](SDK.en.md)
- [中文发布说明](RELEASE_NOTES_v0.2.0.md)