Semblance Foundry Package Plan
Status
- Working name (distribution):
semblance-foundry - Import package:
semblance_foundry - Repository: developed alongside
semblanceunderpackages/semblance-foundry/, independently versioned and publishable - Status: milestones 0–1 implemented (ontology-read MVP). Milestones 2–5 are post–Phase 9.
- Roadmap mapping: Phase 9 is milestones 0–1 (ontology-read MVP). Milestones 2–5 are post–Phase 9.
- Primary objective: provide a deterministic, local HTTP simulation of the public Palantir Foundry REST API for client development, automated tests, demos, and failure-mode testing
semblance-foundry is an unofficial compatibility package. It must not claim
affiliation with, endorsement by, or complete behavioral parity with Palantir.
The package should document the Foundry API documentation revision or date against
which each supported operation was implemented.
Public API v2 operations in this plan are verified against documentation dated
2026-08-18 unless a newer verification pass is recorded in compatibility.yaml.
1. Problem Statement
Teams integrating with Foundry currently need a live enrollment, credentials, and test data to exercise client code. This makes local development and CI slower, introduces external state, and makes edge cases such as throttling, failed actions, or paginated responses difficult to reproduce.
The package will run a local FastAPI application whose paths, request shapes, response shapes, status codes, pagination, and state transitions resemble selected public Foundry API v2 operations. It will use Semblance for route registration, schema-driven generation, seeded output, latency/error simulation, and test integration while adding Foundry-specific behavior in a thin compatibility layer.
2. Goals
- Let existing HTTP clients target a local base URL with minimal or no code changes.
- Support both generated sample data and user-supplied fixtures.
- Preserve process-local state across related calls when enabled (fixture graph for Phase 9; actions and dataset transactions later).
- Produce deterministic results from a seed so failures are reproducible.
- Model Foundry conventions consistently: bearer authentication, resource identifiers (RIDs), API names, page tokens, error envelopes, and request IDs.
- Allow users to enable only the services and resources needed by a test.
- Make supported behavior explicit and testable through a compatibility matrix.
- Remain useful directly as a Python fixture, as an ASGI app, and as a standalone local server.
3. Non-goals
- Reimplementing Foundry's storage, compute, permissions, or ontology engine.
- Executing real transforms, SQL, models, functions, or arbitrary Foundry logic.
- Perfect parity with undocumented behavior or private/internal APIs.
- Acting as a security emulator or validating real Palantir credentials.
- Proxying production traffic or storing production secrets.
- Covering every public API family in the first release.
- Promoting Foundry-shaped pagination, error envelopes, RIDs, or auth into core Semblance unless a second adapter immediately needs the same primitive.
4. Target Users and Core Scenarios
- Client-library tests: point an HTTP or Foundry SDK client at the local server and assert request construction and response handling.
- Application development: unblock UI and service work before a Foundry enrollment or ontology is ready.
- Contract tests: verify an integration against pinned request/response models and known endpoint semantics.
- Failure testing: deterministically simulate authorization failures, missing resources, conflicts, throttling, service errors, and latency.
- Demo environments: load a small ontology fixture without a live Foundry dependency (dataset fixtures come after Phase 9).
5. Package and Repository Layout
Keep the adapter isolated from the core library so Foundry-specific models and
release cadence do not expand semblance itself. Shared conventions with the
planned Databricks adapter: factory + config object, CLI verbs
(serve, validate, fixture init, operations), and a per-operation
compatibility manifest.
Phase 9 creates only the ontology service tree. datasets/, orchestration/,
and streams/ directories wait until those milestones.
packages/
semblance-foundry/
pyproject.toml
README.md
CHANGELOG.md
src/
semblance_foundry/
__init__.py
app.py # FoundryMock factory and ASGI construction
cli.py # serve, validate, fixture init, operations
config.py # typed configuration
auth.py # configurable bearer-token simulation
errors.py # Foundry-style error responses
ids.py # deterministic RIDs and PageTokenCodec
registry.py # service/operation registration
state.py # process-local FoundryState
compatibility.py # manifest load/publish
models/ # shared and service-specific Pydantic models
services/
ontologies/ # Phase 9 read operations
fixtures/ # loaders and bundled minimal examples
py.typed
tests/
unit/
contract/
integration/
fixtures/
Logical layers map onto those modules; they are not a second directory tree:
| Layer | Modules |
|---|---|
| contracts | compatibility.py, models/, registry.py |
| transport | app.py, auth.py, errors.py, cli.py |
| runtime | state.py, ids.py (PageTokenCodec) |
| adapters | services/ontologies/ |
| io | fixtures/ |
Workspace pythonpath, ruff, and mypy entries for packages/semblance-foundry/src
are Phase 11 work (already started at the repo root). Phase 9 plugs tests into
those paths rather than owning the monorepo CI matrix. The adapter depends on
semblance through a normal version constraint; a development extra may reference
the repository checkout.
6. Public API Proposal
The smallest useful API is a factory plus a configuration object:
from semblance_foundry import FoundryMock, FoundryMockConfig
foundry = FoundryMock(
FoundryMockConfig(
seed=42,
auth="optional",
stateful=True,
)
)
foundry.load_fixture("tests/fixtures/acme.yaml")
app = foundry.as_fastapi()
Testing should not require a listening socket:
def test_lists_employees(foundry_client, foundry_mock):
foundry_mock.ontologies.add_objects(
ontology="acme",
object_type="Employee",
objects=[{"employeeId": "1", "name": "Ada"}],
)
page = foundry_client.ontologies.OntologyObject.list(
ontology="acme",
object_type="Employee",
)
assert page.data[0]["name"] == "Ada"
Proposed command-line interface:
semblance-foundry serve --fixture foundry.yaml --port 8765
semblance-foundry validate foundry.yaml
semblance-foundry fixture init --output foundry.yaml
semblance-foundry operations
Environment variables should mirror the concepts a client already uses while
remaining clearly local, for example SEMBLANCE_FOUNDRY_HOST and
SEMBLANCE_FOUNDRY_TOKEN.
Proposed programmatic helpers:
from httpx import AsyncClient
from semblance_foundry.testing import FoundryMockContext
async def test_search(foundry_client: AsyncClient):
async with FoundryMockContext(seed=7, fixture="fixtures/acme.yaml") as server:
async with AsyncClient(base_url=server.base_url, timeout=30) as client:
response = await client.get("/api/v2/ontologies/acme/objects/Employee")
assert response.status_code == 200
FoundryMockContext should support both with and pytest fixtures:
- one-shot in-memory fixture loading
- per-test automatic state reset
- optional shared state across a test session
7. Compatibility Model
Compatibility is defined per operation, not for the platform as a whole. Each
operation in compatibility.yaml should record:
- HTTP method and path template
- API family and version
- support level:
exact,representative,stub, orunsupported - request fields and validation constraints covered
- response and error variants covered
- stateful side effects, if any
- upstream documentation URL and last verification date
- tests that prove the declared level
Release notes must call out compatibility changes. Unknown endpoints return a
normal 404. Known but deliberately unimplemented operations may return a
recognizable 501 response only in strict mode.
Suggested compatibility.yaml schema:
packageVersion: "0.1.0"
documentedAt: "2026-08-18"
source: "https://www.palantir.com/docs/foundry/api/v2"
operations:
- operationId: ListObjectTypes
method: GET
path: /api/v2/ontologies/{ontology}/objectTypes
supportLevel: exact
supports:
- pageSize
- pageToken
limits:
maxPageSize: 1000
tests:
- tests/contract/test_ontology_types.py::test_list_types
The manifest is emitted as /.well-known/foundry-mock-compatibility.json and
included in packaging output so users can diff local behavior against a pinned
compatibility set.
8. Endpoint Scope
Phase A: Ontology read operations (Phase 9 / MVP)
Pinned public API v2 list (docs dated 2026-08-18). Search is representative,
not exact. Query execute stays in the MVP.
| Operation | Method and path | Support |
|---|---|---|
| List ontologies | GET /api/v2/ontologies |
exact |
| Get ontology | GET /api/v2/ontologies/{ontology} |
exact |
| List object types | GET /api/v2/ontologies/{ontology}/objectTypes |
exact |
| Get object type | GET /api/v2/ontologies/{ontology}/objectTypes/{objectType} |
exact |
| List objects | GET /api/v2/ontologies/{ontology}/objects/{objectType} |
exact |
| Get object | GET /api/v2/ontologies/{ontology}/objects/{objectType}/{primaryKey} |
exact |
| Search objects | POST /api/v2/ontologies/{ontology}/objects/{objectType}/search |
representative (eq/and filters only) |
| List linked objects | GET /api/v2/ontologies/{ontology}/objects/{objectType}/{primaryKey}/links/{linkType} |
exact |
| List / get action types | GET /api/v2/ontologies/{ontology}/actionTypes and get-by-name |
exact (metadata; no apply) |
| List / get query types | GET /api/v2/ontologies/{ontology}/queryTypes and get-by-name |
exact |
| Execute query | POST /api/v2/ontologies/{ontology}/queries/{queryApiName}/execute |
representative (static fixture or allow-listed Python callback; never eval fixture expressions) |
Also in Phase 9:
- cursor pagination through
pageSize,pageToken, andnextPageToken - basic property selection and deterministic ordering where documented
- an example ontology with object types, link types, objects, action-type metadata, and one query type
Cursor tokens are owned by the adapter (PageTokenCodec). Core Semblance stays
offset/limit (PageParams / PaginatedResponse); do not block MVP on a core
pagination redesign.
Phase B: Ontology writes and richer queries (post–Phase 9)
- apply an action and apply action batch
- configurable action handlers that may create, update, link, or delete objects
- aggregate objects and object sets
- temporary object sets
- attachment metadata and small in-memory attachment content
- configurable action validation failures and result modes
Action handlers are local test callbacks. They must never execute arbitrary code from an untrusted fixture file.
Phase C: Datasets and transactions (post–Phase 9)
- create and get datasets
- branches: create, list, get, and delete
- schemas: get and put
- transactions: create, get, commit, and abort
- files: upload, list, read, and delete where part of the selected public contract
- read table data from fixture-backed rows
Dataset content should use a pluggable storage abstraction. The default backend can
store metadata and small byte payloads in memory; a temporary-directory backend can
cover larger integration tests. Transaction state must enforce a simple lifecycle
(OPEN -> COMMITTED or OPEN -> ABORTED) and reject invalid transitions.
Phase D: Orchestration and streams (post–Phase 9)
- schedules: get, run, pause, unpause, and list runs
- builds and jobs with configurable asynchronous state progression
- streaming dataset and stream metadata
- publish and consume JSON or binary records
- reset streams and retrieve end offsets
Async resources should use a deterministic virtual clock or explicit
advance() hook by default, avoiding sleep-based tests.
Deferred
Models, SQL execution, media/time-series streaming, websites, Notepad, Workbench, LLM proxy APIs, and beta or enrollment-specific APIs remain out of scope until a concrete user need and contract-test strategy exist.
9. Data and Fixture Design
Use YAML or JSON for declarative fixtures, validated into Pydantic models before
the server starts. Phase 9 fixtures describe the ontology graph (types, objects,
links, action/query metadata). Apply-action behavior blocks belong to Phase B.
version: 1
ontologies:
- apiName: acme
objectTypes:
- apiName: Employee
primaryKey: employeeId
objects:
- employeeId: "1"
name: Ada Lovelace
- apiName: Office
primaryKey: officeId
objects:
- officeId: "hq"
name: Headquarters
linkTypes:
- apiName: worksAt
from: Employee
to: Office
objects:
- from: "1"
to: "hq"
actionTypes:
- apiName: renameEmployee
parameters:
- employeeId
- newName
queryTypes:
- apiName: employeesByOffice
result:
type: static
objects:
- employeeId: "1"
name: Ada Lovelace
Fixture requirements:
- reject duplicate API names and primary keys at load time
- validate links and action/query type references before serving
- generate omitted RIDs deterministically from stable fixture identity
- support composition of multiple fixture files with explicit conflict rules
- support user extensions without allowing silent unknown fields in strict mode
- provide a Python builder API for cases that are awkward or unsafe to express in data files
- never evaluate expressions or callbacks from YAML; custom query (and later action) behavior is allow-listed Python only
Generated data is useful for volume tests, but explicit fixtures take precedence. Generation rules should be seeded and attach stable primary keys so pagination and links remain repeatable.
10. Request and Response Semantics
Authentication and authorization
Three modes:
disabled: ignore authorization for the shortest local setupoptional(default): accept any syntactically valid bearer token and expose hooks for per-operation denialstrict: require tokens declared in test configuration with scopes and resource grants
This is a behavioral test double, not an OAuth server. Authentication errors must never echo token contents.
IDs and headers
- Generate stable Foundry-like RIDs for fixtures that omit them.
- Include a deterministic request identifier header, with an override hook for tests.
- Preserve documented content types for JSON and binary endpoints.
Response shaping and timing
- Content negotiation should support
application/jsonand documented binary alternatives where applicable. - Optional minimum-latency jitter per route to emulate transport variance while keeping request ordering deterministic.
- If
Prefer: respond-async(or equivalent client hint) is received, routes can return 202 with server-side job metadata when supported by an operation (not required for Phase 9 reads).
Pagination
- Page tokens must be opaque to clients, URL-safe, and checksummed to detect
tampering (
PageTokenCodecin the adapter). - Tokens should encode a resource revision so mutation between pages can trigger a configured consistency behavior.
- Invalid, expired, or cross-endpoint tokens should produce a documented-style client error rather than silently restarting at page one.
Errors and simulation
Create a central exception-to-response mapper for validation, authentication, permission, missing resource, conflict, throttling, and internal failures. Add global defaults and per-operation overrides for latency, error probability, fixed errors, and rate limits. Error injection must occur at defined points so tests can choose whether a failed write happens before or after a state mutation (writes are post–Phase 9).
11. Architecture
flowchart LR
C["HTTP or SDK client"] --> A["FoundryMock FastAPI app"]
A --> M["Auth and error middleware"]
M --> R["Foundry operation registry"]
R --> S["Semblance route and simulation primitives"]
R --> H["Foundry-specific handlers"]
H --> ST["Typed state store"]
H --> FX["Validated fixture registry"]
ST --> P["In-memory store"]
Core vs adapter: Semblance owns generic HTTP simulation (route registration,
schema-driven generation, seeding, latency/error knobs, test helpers). The adapter
owns Foundry-specific envelopes, RIDs, cursor tokens, and auth. Promote a primitive
to core only if a second consumer (for example semblance-databricks) proves the
same generic need, behind a generic API, tested independently.
Key internal abstractions:
FoundryOperation: method, path, request/response types, compatibility metadata, and handlerFoundryState: ontologies, objects, and links for Phase 9; datasets, transactions, streams, and asynchronous resources laterPageTokenCodec: opaque token creation and validationFoundryError: typed error code, name, parameters, and HTTP mappingBehaviorRegistry: allow-listed Python callbacks for query execute (Phase 9) and actions (Phase B)StorageBackend: in-memory for Phase 9; temporary-directory persistence when dataset support lands
12. Testing Strategy
Unit tests
- fixture validation and deterministic RID generation
- page-token round trips, tampering, and resource revision checks
- authentication modes and scope decisions
- error serialization and simulation ordering
Endpoint contract tests
HTTP contract tests are required for every supported Phase 9 operation:
- canonical success request and response
- required/optional parameters and unknown-field behavior
- documented pagination behavior where applicable
- common error statuses and response envelope
- JSON field aliases and omission of optional/null fields where required
Maintain sanitized, hand-authored golden fixtures derived from public documentation. Do not require live Foundry access in the default test suite. No network in unit or contract tests.
Client compatibility tests
- Raw
httpxtests distinguish wire-contract bugs from SDK behavior. - One pinned
foundry-platform-sdkversion is the compatibility acceptance test. Keep it optional/non-blocking if the SDK cannot target localhost in CI. - A scheduled job may later test the newest compatible SDK until support policy is established.
Fuzz and negative testing
- property-based checks for fixture conflict handling
- random request permutations for unsupported fields and query combinations
- contract drift tests ensuring unsupported required query params produce stable errors rather than silently accepted values
Quality gates
- Python 3.10, 3.11, and 3.12
- Ruff, mypy, pytest, and coverage thresholds consistent with the parent project
- no network access in unit and contract suites
- deterministic test results regardless of test order
- package build plus clean-environment installation smoke test
13. Documentation Deliverables
Phase 9 (package README and stubs; no user-facing Foundry guides on the core docs site until the package exists):
- quick start for direct HTTP clients (and SDK if CI-feasible)
- fixture format reference with a complete example
- operation compatibility matrix
- authentication and failure-simulation guide
- explicit trademark, security, and non-affiliation notice
- a “known unsupported” checklist (apply/applyBatch, datasets, orchestration)
Post–Phase 9:
- recipes for actions, linked-object mutations, transactions, and streams
- migration notes for compatibility changes
- a minimal example app for both
httpxand the official SDK
14. Delivery Milestones
Milestone 0: Contract and packaging spike (Phase 9)
- scaffold the independent package under
packages/semblance-foundry/ - confirm whether the official Python SDK can target a local hostname
- implement one vertical slice: list ontologies and object types with auth, pagination, and one error
- keep Foundry-specific pagination/auth in the adapter (do not extend core unless a generic primitive is proven)
- publish the initial compatibility manifest
Exit criterion: an HTTP client lists two fixture-backed object types (and, if CI-feasible, the pinned SDK does the same) without a live Foundry service.
Milestone 1: Ontology read MVP (Phase 9)
- implement the pinned Phase A operations
- add fixture loader, deterministic IDs, three auth modes, and core errors
- ship pytest fixtures and standalone CLI (
serve,validate,fixture init,operations) - document all supported and unsupported operations
Exit criterion (Phase 9 done): HTTP client (and SDK if CI-feasible) lists fixture objects across two pages, gets by primary key, follows one link, and executes one configured query — all locally.
Milestone 2: Stateful ontology behavior (post–Phase 9)
- implement actions, batch actions, aggregates, and object sets
- add safe Python behavior hooks and declarative built-in action behaviors
- cover mutation failures and state isolation between tests
Exit criterion: an action changes an object and subsequent reads reflect the change, with deterministic success and failure tests.
Milestone 3: Dataset workflows (post–Phase 9)
- implement datasets, branches, schemas, transactions, files, and table reads
- add in-memory and temporary-directory storage backends
Exit criterion: a client creates a transaction, writes fixture content, commits it, and reads the resulting dataset state.
Milestone 4: Orchestration and streaming (post–Phase 9)
- implement selected schedules, builds, jobs, and stream operations
- add virtual-clock state progression and record offsets
Exit criterion: tests can drive an asynchronous build lifecycle and a publish/consume stream cycle without wall-clock waits.
Milestone 5: Hardening and first stable release (post–Phase 9)
- run compatibility review against the pinned public API documentation revision
- finalize versioning and upstream SDK support policy
- complete security, packaging, performance, and documentation review
- publish
1.0.0only when support levels and breaking-change policy are reliable
Phase 9 implementation sequence
Merge of the former sprint backlog and immediate repository work. No calendar estimates.
- Scaffold
packages/semblance-foundry/(pyproject.toml,src/semblance_foundry,FoundryMock/FoundryMockConfigexport, test layout, README / CHANGELOG / non-affiliation notice). - Define fixture v1 schema, bundled example fixture, and
compatibility.yaml. - Vertical slice:
GET /api/v2/ontologiesandGET /api/v2/ontologies/{ontology}/objectTypeswith auth middleware, request-id, deterministic RIDs, and one golden contract test. - Remaining Phase A read operations, cursor pagination, search (eq/and), links, action/query type metadata, and query execute.
- CLI (
serve,validate,fixture init,operations) and MVP docs.
Every milestone finishes with updated compatibility rows. Plug tests into existing workspace paths from Phase 11; do not invent a second CI matrix in this package.
15. Versioning and Support Policy
- Version
semblance-foundryindependently using semantic versioning. - Pin a compatible range of
semblancereleases and test its lower and upper bounds. - Treat changes to response shape, default strictness, fixture schema, and stateful behavior as compatibility-sensitive.
- Version the fixture schema separately from the Python package and provide migrations for breaking fixture changes.
- State supported official SDK versions in package metadata or documentation; do not imply that untested versions are compatible.
16. Risks and Mitigations
| Risk | Mitigation |
|---|---|
| The public API changes frequently | Pin documentation verification dates, automate contract inventory checks where permitted, and publish per-operation support levels. |
| “Mock Foundry” implies unrealistic completeness | Use precise endpoint-level claims and return explicit unsupported-operation errors in strict mode. |
| Stateful behavior becomes a second platform implementation | Limit behaviors to observable test contracts and keep compute/query execution callback-based. |
| SDKs enforce HTTPS or hostname assumptions | Prove local endpoint configuration in Milestone 0; keep SDK tests optional/non-blocking if they cannot target localhost. |
| Fixture files become an arbitrary-code vector | Keep declarative fixtures data-only; require allow-listed Python for custom callbacks and never evaluate fixture expressions. |
| Large files or object volumes exhaust memory | Stay in-memory for Phase 9; add a temporary-directory backend and configurable limits before dataset support is declared stable. |
| Trademark or licensing confusion | Use an explicit unofficial/non-affiliation notice and avoid copying generated SDK code or proprietary schemas. |
17. Locked Decisions
These were open before Phase 9 refinement. They are now decided:
- Consumers: raw HTTP and
foundry-platform-sdkagainst the same ASGI app. HTTP contract tests are required for MVP. One pinned SDK version is the compatibility acceptance test (optional/non-blocking if the SDK cannot target localhost in CI). - Repo:
packages/semblance-foundry/in this repository, independently versioned, depending onsemblancevia a normal version range. - Auth default:
optional. Also documentdisabledandstrict. Never echo tokens. CI examples useoptionalunless a test is specifically coveringstrict. - Persistence: process-local only for MVP. No restart durability before 1.0.
- Phase 9 exit: ontology-read MVP (milestones 0–1), not Foundry 1.0.
- Cursor pagination: implement in the adapter (
PageTokenCodec). Do not add Foundry-shaped helpers to core in Phase 9 unless a second adapter immediately needs the same primitive. - Unknown vs unimplemented: unknown paths → 404; known-but-unimplemented
operations may return 501 only in
strictmode. - Phase A operations and docs date: the pinned table in §8, verified against public API v2 documentation dated 2026-08-18.
18. Definition of Done for the MVP
The Ontology read MVP (Phase 9) is complete when:
- the package installs independently and exposes typed public APIs
(
FoundryMock,FoundryMockConfig,as_fastapi()) - a raw HTTP client passes the ontology-read scenarios below; a configured official Python SDK client passes the same scenarios when CI-feasible
- fixtures define at least one ontology, two object types, linked objects, one action type (metadata only), and one query type
- object listing supports stable cursor pagination and property selection
- HTTP client lists fixture objects across two pages, gets by primary key, follows one link, and executes one configured query — all locally
- missing resources, invalid requests, invalid tokens, denied access, throttling, and injected server failure each have deterministic tests
- test state is isolated and resettable without restarting the process
- the compatibility matrix links every implemented operation to its tests and the public documentation used
- README, fixture reference, limitations, security guidance, and non-affiliation notice are complete
- build, lint, type-check, and test jobs pass for all supported Python versions
Foundry 1.0.0 criteria remain under Milestone 5 and are not part of this DoD.