POLARIS Archive Integration¶
Duration: 90 minutes
Level: Advanced
Module: fcc.archive.polaris_bridge, fcc.api.archive
Bridge: v1.5.0 stable promotion
This tutorial teaches you how to integrate with POLARIS — the long-term archive
service in the FCC ecosystem — through the stable fcc.api.archive surface.
You will learn the three-method protocol (push_archive, pull_archive,
query_models), when to use the functional mock versus the real adapter, how
to write manifests that survive decades of storage, and the tar-manifest
discipline that the LTAS persona enforces.
What POLARIS is (and is not)¶
POLARIS (Persistent Object + Longitudinal Archive Repository for Integrated Studies) is the long-term archival service in the FCC ecosystem. Its job:
- Preserve model artifacts, dataset snapshots, and R.I.S.C.E.A.R. specifications
- Verify content integrity with SHA-256 addressing
- Catalog everything by Zachman cell, retention policy, and provenance
- Retrieve artifacts on demand a decade later
POLARIS is not an active data store. It is not a database, not a cache, and
not the right place for artifacts you query frequently. Every pull_archive
is a cold-storage retrieval — POLARIS is the place for things you need to keep
but do not need to touch often.
The production backend is ice_ext.plugin.bridge.ICEFacadeAdapter. When
ice_ext is not installed (the default in most FCC-only environments), the
stable API returns a functional in-memory mock. Your code stays identical
either way.
The stable surface — fcc.api.archive¶
v1.5.0 promoted the POLARIS bridge from the fcc.plugins.v1_5_preview
namespace into the canonical fcc.api.archive surface. All public symbols
are now covered by the same 1.x SemVer backward-compatibility guarantee as
the rest of fcc.api.*.
# Preferred — stable top-level API
from fcc.api import archive
# Equivalent — direct module import
from fcc.archive.polaris_bridge import (
get_polaris_bridge,
PolarisBridgeProtocol,
PolarisMockBridge,
NoOpPolarisBridge,
polaris_available,
)
The preview path fcc.plugins.v1_5_preview.polaris_bridge still works through
v1.5.x with a DeprecationWarning emitted on import so CI surfaces the
migration signal. The preview path is removed in v1.6.0.
The three-method protocol¶
@runtime_checkable
class PolarisBridgeProtocol(Protocol):
def push_archive(self, manifest_path: Path) -> str: ...
def pull_archive(self, archive_id: str) -> Path: ...
def query_models(self, **filters: Any) -> list[dict]: ...
That is the entire surface. Every implementation — the production adapter, the functional mock, and the no-op fallback — agrees on exactly these three methods. Callers can swap implementations by replacing the factory call; no other code needs to change.
Push: archiving an artifact¶
Archiving is manifest-first. You never push raw bytes; you push a path to a
manifest file that describes the artifact. The bridge computes a content-
derived archive_id (SHA-256 of the manifest bytes, truncated to 16 hex
chars with an archive- prefix), stores the descriptor, and returns the id.
from pathlib import Path
from fcc.api import archive
bridge = archive.get_polaris_bridge()
# Write a manifest alongside your artifact
manifest = Path("/tmp/model-manifest.yaml")
manifest.write_text("""\
content_type: application/onnx
artifact_path: /tmp/model.onnx
content_sha256: abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789
created_at: 2026-04-23T10:00:00Z
riscear_ref: persona:MAR
retention: 10y
zachman_cell: engineer:what
tags:
- production
- model-registry
""", encoding="utf-8")
archive_id = bridge.push_archive(manifest)
print(f"archived as {archive_id}")
# archived as archive-a1b2c3d4e5f6g7h8
The mock bridge never materializes a tarball — it stores the manifest
descriptor in an in-memory dict. The real ICEFacadeAdapter drives the full
POLARIS storage pipeline (tarball + replication + retention enforcement), but
the call site is identical.
Pull: retrieving an artifact¶
pull_archive(archive_id) returns the local filesystem path where the
artifact (or, in the mock, the manifest) was written. The id is the stable
handle you stored after push; archive ids are immutable, so the same id
always returns the same artifact.
restored = bridge.pull_archive(archive_id)
print(f"restored: {restored}")
print(restored.read_text()[:200])
Unknown archive ids raise KeyError. Wrap in a try/except when retrieving ids
from long-lived storage; an id that was valid five years ago may have been
retention-expired since.
Query: finding archived artifacts¶
query_models(**filters) returns a list of archive descriptor dicts matching
the filter criteria. Supported filter keys:
| Filter | Type | Behavior |
|---|---|---|
zachman_cell |
str |
Exact string match on the manifest's Zachman cell |
created_after |
datetime |
Strict lower bound on created_at |
size_min |
int |
Inclusive lower bound on size_bytes |
size_max |
int |
Inclusive upper bound on size_bytes |
Unknown filter keys are tolerated — callers can pass extra metadata freely without breaking the query.
from datetime import datetime, timezone, timedelta
# Everything archived in the last 30 days under the engineer:what cell
cutoff = datetime.now(timezone.utc) - timedelta(days=30)
results = bridge.query_models(
zachman_cell="engineer:what",
created_after=cutoff,
size_min=1024,
)
for descriptor in results:
print(f" {descriptor['archive_id']}: "
f"{descriptor['size_bytes']} bytes "
f"at {descriptor['created_at']}")
Each descriptor includes archive_id, manifest_path, created_at,
size_bytes, zachman_cell, and the parsed metadata dict from the
manifest.
Mock vs real — the factory¶
get_polaris_bridge() is the safe default: it returns the live adapter when
ice_ext is importable and the functional PolarisMockBridge otherwise.
from fcc.api.archive import get_polaris_bridge, polaris_available
print(f"POLARIS installed? {polaris_available()}") # True iff ice_ext is importable
bridge = get_polaris_bridge() # works regardless
Explicitly constructing a specific implementation is useful in tests:
from fcc.archive.polaris_bridge import PolarisMockBridge, NoOpPolarisBridge
# Tests that want a functional in-memory store
mock = PolarisMockBridge()
# Tests that want to verify degraded-mode behavior
noop = NoOpPolarisBridge() # returns "" / Path() / [] and warns
NoOpPolarisBridge is for the narrow case of verifying that your code
tolerates empty responses (warning-emitting no-ops). The default is
PolarisMockBridge, which is a fully working in-memory implementation — use
it for demos, tests, and CI without any network or disk dependency beyond the
manifest file itself.
When to archive, when to keep hot¶
POLARIS is not the right store for everything. Archive these:
- Finalized model artifacts. After a model is retired from production, push it to POLARIS with a retention policy matching your regulatory regime.
- Compliance audit snapshots. Each EU AI Act audit run should produce a signed manifest + evidence bundle that POLARIS preserves for the full record-keeping period (10 years for high-risk systems).
- Published R.I.S.C.E.A.R. specifications. Each persona catalog release gets a POLARIS snapshot so future audits can verify which spec was live on a given date.
- Immutable reference data. Third-party vocabulary releases, regulatory text, canonical ontologies.
Keep these hot:
- Anything you query more than once per day. Use the object model or knowledge graph instead.
- Work-in-progress artifacts. POLARIS is not a version control system; it is the final resting place after versioning is done.
- Data subject to frequent redaction. Content-addressed archives make redaction expensive — you cannot "edit" a POLARIS artifact, only supersede it with a new id and a tombstone record.
The LTAS persona (Long-Term Archive Steward) is the designated owner of this judgment call. Consult your LTAS before archiving anything with sensitive or frequently-changing content.
Tar-manifest discipline (LTAS)¶
A manifest is only as good as its fields. The LTAS persona enforces these rules — your manifests should follow them whether or not you have an LTAS on staff:
Required fields:
content_type— MIME type or vendor-specific type (e.g.application/onnx)content_sha256— full 64-char hex SHA-256 of the artifact payloadcreated_at— ISO-8601 UTC timestampretention— retention period (10y,7y,indefinite)
Strongly recommended:
riscear_ref— reference to the persona/workflow that owns this artifactzachman_cell— row:col coordinate for catalogingartifact_path— absolute path to the actual payload if separate from manifesttags— list of string tags for downstream discoverydependencies— list of other archive ids this artifact depends on
Never store in a manifest:
- Secrets, API keys, PII of any kind — manifests are cataloged and indexed
- Timestamps as Unix epoch integers — always use ISO-8601
- References to mutable external URLs — pin with a content hash
A well-disciplined manifest is readable by a future auditor with zero context on your deployment. Write them as though that auditor is three years in the future and three layers removed from your team.
Archive entries and restore requests¶
The functional mock exposes the full push/pull/query cycle. Here is an end-to-end example: archive three models, query by cell + date, and restore one.
import tempfile
from datetime import datetime, timezone, timedelta
from pathlib import Path
from fcc.api.archive import get_polaris_bridge
bridge = get_polaris_bridge()
workdir = Path(tempfile.mkdtemp())
# 1. Three manifests
manifests = []
for n in range(3):
m = workdir / f"manifest-{n}.yaml"
m.write_text(f"""
content_type: application/onnx
content_sha256: {'0' * 64}
created_at: {datetime.now(timezone.utc).isoformat()}
riscear_ref: persona:MAR
retention: 10y
zachman_cell: engineer:what
tags:
- model-v{n}
""".strip(), encoding="utf-8")
manifests.append(m)
# 2. Push all three
ids = [bridge.push_archive(m) for m in manifests]
print(f"archived {len(ids)} models: {ids}")
# 3. Query
results = bridge.query_models(
zachman_cell="engineer:what",
created_after=datetime.now(timezone.utc) - timedelta(minutes=5),
)
print(f"found {len(results)} matching archives")
# 4. Restore one
restored_path = bridge.pull_archive(ids[0])
print(f"restored: {restored_path}")
# 5. Integrity check — the id is derived from manifest content, so a re-push
# of the same manifest yields the same id.
re_id = bridge.push_archive(manifests[0])
assert re_id == ids[0], "content-addressed id should be stable"
Live bridge integration¶
When the ice_ext package is installed (via the LYRA/POLARIS infrastructure
release), polaris_available() returns True and get_polaris_bridge()
returns the real ICEFacadeAdapter. No code changes are needed on the FCC
side — the factory does the switch for you.
To verify in staging without changing code:
from fcc.api.archive import get_polaris_bridge, polaris_available
if polaris_available():
bridge = get_polaris_bridge()
print(f"live bridge: {type(bridge).__name__}")
else:
print("ice_ext not installed; mock in use")
Feature-flag your integration tests to skip when polaris_available() is
False — mock tests cover functional correctness, live tests add the network +
retention + replication path.
Archiving compliance audit evidence¶
A real example: after a ComplianceAuditor run, archive the evidence bundle
so the audit can be reproduced years later.
import hashlib
import json
import tempfile
from pathlib import Path
from datetime import datetime, timezone
from fcc.api import archive
from fcc.personas.registry import PersonaRegistry
bridge = archive.get_polaris_bridge()
# Your audit evidence (structure depends on your auditor)
evidence = {
"auditor_version": "fcc-1.5.0",
"run_id": "audit-2026-04-23-001",
"personas": ["RC", "DGS", "DE"],
"requirements_evaluated": 256,
"findings": [],
}
evidence_bytes = json.dumps(evidence, sort_keys=True).encode("utf-8")
evidence_sha = hashlib.sha256(evidence_bytes).hexdigest()
workdir = Path(tempfile.mkdtemp())
manifest_path = workdir / "manifest.yaml"
evidence_path = workdir / "evidence.json"
evidence_path.write_bytes(evidence_bytes)
manifest_path.write_text(f"""
content_type: application/json
artifact_path: {evidence_path}
content_sha256: {evidence_sha}
created_at: {datetime.now(timezone.utc).isoformat()}
riscear_ref: audit:{evidence['run_id']}
retention: 10y
zachman_cell: planner:why
tags:
- eu-ai-act
- audit-evidence
""".strip(), encoding="utf-8")
archive_id = bridge.push_archive(manifest_path)
print(f"audit archived as {archive_id}")
# Register the archive id in the auditor's provenance chain
Ten years from now, an auditor pulls archive_id, verifies the SHA-256
matches the manifest's content_sha256, and reruns the audit against the
preserved evidence. Content addressing guarantees the evidence they see is
the evidence you archived.
Troubleshooting¶
ValueError: manifest not found. The push_archive method requires the
manifest file to exist on disk. Create the file before calling push.
KeyError: no archive with id .... The archive id has not been pushed
yet (or has been evicted on a non-persistent mock). For the real bridge,
retention expiry is a legitimate cause of KeyError — wrap pulls in retry
logic only for transient failures, never for retention-expired archives.
Duplicate archive ids. Expected. The id is SHA-256 of the manifest, so
two calls with the same manifest bytes yield the same id. This is a feature
— it makes re-pushes idempotent. Verify by comparing descriptors returned
from query_models.
Mock data vanishes after process restart. PolarisMockBridge is
in-memory. For persistent test fixtures, write your own
PolarisBridgeProtocol implementation backed by a sqlite file or the
file system.
Production bridge hangs. The ICEFacadeAdapter performs network I/O
with configurable timeouts. Wrap production calls in a timeout guard; do not
block a request thread on a slow archive retrieval.
Summary¶
In this tutorial you learned how to:
- Use the stable
fcc.api.archivesurface for push / pull / query - Write manifests with the required LTAS-approved fields
- Decide when to archive vs keep hot
- Use
PolarisMockBridgefor tests and demos withoutice_ext - Switch seamlessly to the live
ICEFacadeAdapterwhen available - Archive compliance audit evidence with content-addressed integrity
Next steps¶
- Stand up a nightly archive job that snapshots your persona catalog to POLARIS with a 10-year retention policy
- Wire the LTAS persona into your change-management process so archival decisions run through a designated reviewer
- Build a restore-request CLI on top of
pull_archivefor audit teams
Related tutorials¶
- LYRA Knowledge Graph Integration — the partner bridge
- EU AI Act Compliance — evidence bundles that get archived
- Compliance Getting Started — upstream audit flow
- Federation — cross-project entity resolution
Related references¶
- ADR-008 POLARIS absorption —
docs/decisions/ADR-008_polaris_absorption.md - Codename decoder —
docs/ecosystem/codename-decoder.md - POLARIS bridge chapter stub —
publications/chapters/integ/polaris-bridge.qmd - Source —
src/fcc/archive/polaris_bridge.py,src/fcc/plugins/v1_5_preview/polaris_bridge.py - Class diagram —
docs/architecture/class-diagrams/polaris-bridge.md