Skip to content

feat(server): add protocol discovery and persistent identity - #1753

Merged
hidb4ai merged 12 commits into
oceanbase:masterfrom
wutongyuonce:feat/server-info-1655
Oct 11, 2026
Merged

hidb4ai merged 12 commits into
oceanbase:masterfrom
wutongyuonce:feat/server-info-1655

Conversation

@wutongyuonce

@wutongyuonce wutongyuonce commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Which issue or RFC does this PR close?

Closes #1655.

Rationale

Remote consumers need an authenticated protocol handshake and a durable logical deployment identity, distinct from health, runtime capabilities, Access identity, and proof of trust.

Contract and current design

The wire authority is openapi/powercontext.yaml. Detailed lifecycle, compatibility, restore/clone, and migration boundaries are documented in the English design and Chinese design.

  • GET /v1/server-info requires server.observe under the configured authentication/authorization policy. It returns schema_version, product, server_id, package_version, api_contract_version, and feature_contracts; no secrets, paths, health, capabilities, inventory, or principal data.
  • Initial schema: 1.0; API contract: 1.2; features: access.principal, scope.selection, and memory.explicit, each 1.0. Versions require integer major >= 1, minor >= 0. Minor changes are backward compatible; incompatible changes increment major.
  • OpenAPI explicitly owns feature versions and operation membership; the generator validates declarations and emits metadata consumed by Server discovery. Membership edits do not automatically bump versions.
  • A singleton in the Runtime-owned primary relational database preserves server_id across normal restarts, package upgrades, same-deployment restores, and cooperating replicas. It is distinct from Access deployment_id and migration pc_schema_revision.
  • Independent clones must stop all Server processes and run powercontext server identity-reset --maintenance-confirmed. Active-replica detection and fencing are operator responsibilities. Logical data imports copy identity only if they include pc_server_identity.
  • Memory and temporary SQLite databases get a new identity for each database lifetime. Shared-memory data and identity survive while a Runtime connection remains open. SQLite's adapter classifies effective driver arguments and native URI semantics, preserving SQLite's case-sensitive file: prefix and literal filename controls, and honoring decoded NUL termination for filenames and query parameter names/values. is_persistent excludes memory (including the built-in memdb VFS) and empty-path temporary file URIs. Nonpersistent pooling, offline guards, cursor-secret persistence, and subprocess workers consume this single authority. Reset rejects these targets before opening storage.
  • The identity repository retries complete schema/singleton initialization operations only for native SQLite busy/locked errors, including shared-cache table/schema locks. Each operation admits retries within a five-second window with 50 ms waits; SQL attempts retain their configured driver busy timeout. Exhaustion or any other failure aborts startup before readiness. Offline rotation is not retried.
  • Discovery projects one row and static generated metadata. It adds no cache, background job, replica state, or unbounded collection. The Python SDK exposes get_server_info() and accepts unknown optional fields in compatible schema minors.

The current unified migration bundle owns only four Artifact tables, not complete Server startup or pc_server_identity; it rejects complete Server databases with unmanaged objects. Identity remains Runtime-owned within this boundary. Complete-schema migration adoption must preserve the existing singleton; clone rotation remains explicit and offline, with no separate identity migration ledger.

Authority and evidence

Obligation Authority Retained evidence
Wire shape, authorization, API version OpenAPI and generated bindings Contract checks, generated-artifact checks, configured-authentication Server tests
Feature versions and membership OpenAPI and API generator; Server projects metadata Contract projection and generator declaration tests
Singleton durability, restore, rotation and initialization recovery Identity repository Reopen/restore/clone, durable and shared-memory convergence, real held-lock recovery and zero-budget exhaustion
SQLite persistence and native lock classification SQLite adapter Storage classification, temporary database connection lifetime, existing profile regressions
Runtime-owned identity and fail-before-readiness Runtime composition and Server factory HTTP restart, shared Scope/identity lifetime, startup failure
Offline operator procedure Server CLI consuming adapter classification Confirmation without storage creation, reset/reopen readback, nonpersistent rejection
Consumer decoding Python client SDK transport/model test with a future optional field

Tests avoid duplicating the generated feature taxonomy in HTTP assertions or repeating SDK decoding at the model layer. Remaining projection and SDK tests were mutation-checked to reject broken membership and unknown-field handling. Plain repository memory lifetime is covered by the Server shared-data/identity lifecycle seam and persistence tests; no timing or process-memory assertions establish resource bounds.

User-facing changes

Additive endpoint, SDK method, offline maintenance command, and pc_server_identity table. Generated Python/host operation catalogs are included. No breaking API change. This PR does not implement trust establishment, automatic clone detection, client reconnection policy, legacy profile negotiation, or #1656/#1657 pagination/history work.

Validation

  • make check: passed, including lock consistency, prek, ruff, ty, generated API checks, and 49 integration-manifest tests.
  • make unit-test: 4235 passed, 207 skipped.
  • make build: passed.
  • make docs-test: passed; verified 947 public pages and their internal links.
  • Not run locally: end-to-end, evaluation, OceanBase/seekdb, and the multi-version CI matrix. Those remain for hosted CI on this update.

Focused regressions cover temporary and memory URI rejection, native filename classification, shared-memory identity convergence, held-lock recovery, and retry exhaustion. Retained feature-projection and SDK unknown-field tests were mutation-checked against broken obligations.

AI usage statement

OpenAI Codex and Pi-hosted AI assistants were used for analysis, implementation, test drafting, independent review, and validation. Changes were checked against the issue, maintainer feedback, repository conventions, and the explicitly listed verification results. AI review does not replace required maintainer approval.

@wutongyuonce

Copy link
Copy Markdown
Contributor Author

@Teingi Thanks for the review. Both findings are fixed in 154f6a57:

  • Concurrent startup now creates pc_server_identity with atomic CREATE TABLE IF NOT EXISTS before the existing singleton insert-conflict convergence. The regression concurrently opens eight repositories against a missing schema and asserts one shared identity.
  • SQLiteConfig.is_in_memory now recognizes SQLite URI memory forms (mode=memory&uri=true and file::memory:), so identity-reset rejects them instead of reporting a non-durable rotation.

I also updated the English/Chinese lifecycle docs and the PR description. Local validation passed: 191 focused tests, make check, make docs-test (832 pages), make build, and git diff --check. Could you please take another look?

Comment thread src/powercontext/server/factory.py Outdated
Comment on lines +181 to +182
async with open_server_identity_repository(config.database) as identity_repository:
server_id = await identity_repository.load_or_create()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The identity database is closed before the runtime opens it. With shared-memory SQLite, two apps can read the same Scope but return different server_ids. Please initialize the identity using the runtime-owned primary database.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 1f58fe2. Server startup now initializes and loads the identity through runtime.primary_database, borrowing the same database that owns Scope data for the Runtime's lifetime. The separate identity database opener is retained only for the offline CLI. Identity schema creation remains idempotent, and initialization/loading errors still abort startup before readiness.

I reproduced the reported mismatch before the fix. The regression now creates a Scope through one app, reads it through a second app sharing the same SQLite memory URI, and checks that both advertise the same server_id. It also verifies that closing one app preserves the surviving app's data and identity, while reopening after all connections close starts a new database and identity.

Comment thread src/powercontext/server/info.py Outdated
@wutongyuonce

wutongyuonce commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor Author

@PsiACE Both review points are addressed in 1f58fe2, with details in the inline replies. Identity initialization now uses the Runtime-owned primary database, and feature versions/membership are declared in OpenAPI and generated.

Classify memory storage using dialect connection arguments and decoded SQLite URIs so offline reset cannot claim a nonpersistent rotation. Reject feature major zero during generation, matching the discovery model. Extend existing regressions and document both validation boundaries.
@wutongyuonce

wutongyuonce commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor Author

@Teingi Conflicts with current master are resolved in 446c7e3f.

@hidb4ai

hidb4ai commented Oct 10, 2026

Copy link
Copy Markdown

please update & resolve conflicts

@wutongyuonce

Copy link
Copy Markdown
Contributor Author

@hidb4ai Resolved.

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

Reviewed f5b4b98. One low-priority issue remains in the offline identity reset guard; details below.

Comment thread src/powercontext/server/cli.py Outdated

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

Two SQLite identity issues remain at f5b4b988: the shared-memory startup failure detailed below and the temporary-database reset issue, which still reproduces on this commit. Please fix the startup failure before merging.

Comment thread src/powercontext/server/identity.py
Classify persistence from SQLite's own URI rules so offline reset cannot report an identity that disappears on reopen. Retry only busy and locked errors across the complete identity initialization, and keep that classification in the SQLite adapter.
@wutongyuonce

Copy link
Copy Markdown
Contributor Author

Addressed the two remaining SQLite findings in 633823b.

  • Offline reset now rejects native nonpersistent targets before opening storage. Classification stays in the SQLite adapter: case-sensitive file: URIs, literal filename controls, decoded NUL termination, and the built-in memdb VFS.
  • Identity initialization retries only busy/locked errors for the complete rolled-back schema or singleton operation. Rotation is not retried, and non-lock failures still abort startup.

Local make check, unit tests (4235 passed, 207 skipped), package build, and docs test passed. End-to-end, evaluation, OceanBase/seekdb, and the multi-version matrix were not run locally; please use the new hosted CI for those. Not merging.

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

LGTM

@hidb4ai
hidb4ai merged commit 2058325 into oceanbase:master Oct 11, 2026
32 checks passed
@wutongyuonce
wutongyuonce deleted the feat/server-info-1655 branch October 11, 2026 09:09
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.

feat(api): add Server protocol discovery and persistent deployment identity

3 participants