Skip to content

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 payload
  • created_at — ISO-8601 UTC timestamp
  • retention — retention period (10y, 7y, indefinite)

Strongly recommended:

  • riscear_ref — reference to the persona/workflow that owns this artifact
  • zachman_cell — row:col coordinate for cataloging
  • artifact_path — absolute path to the actual payload if separate from manifest
  • tags — list of string tags for downstream discovery
  • dependencies — 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.archive surface for push / pull / query
  • Write manifests with the required LTAS-approved fields
  • Decide when to archive vs keep hot
  • Use PolarisMockBridge for tests and demos without ice_ext
  • Switch seamlessly to the live ICEFacadeAdapter when 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_archive for audit teams
  • 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