Skip to content
Open
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c1ca71b
fix(transport): enforce loopback-only plaintext HTTP policy for Serve…
larry-zy Aug 23, 2026
6ee09c7
Merge branch 'master' into fix/1319-transport-policy
larry-zy Aug 24, 2026
b1547e4
test(transport): pin the Codex plugin to the shared loopback policy
larry-zy Aug 24, 2026
be13bed
fix(transport): treat the whole 127.0.0.0/8 block as loopback
larry-zy Aug 25, 2026
67c1842
fix(client): skip the plaintext-token guard for caller-supplied trans…
larry-zy Aug 25, 2026
8615e7d
fix(e2e): opt the acceptance harness into its non-loopback Server bind
larry-zy Aug 25, 2026
fb4250a
fix(transport): harden the transport-safety policy per PR #1344 review
larry-zy Aug 25, 2026
f991816
fix(server): satisfy ty and make CLI error assertions width-independent
larry-zy Aug 25, 2026
9d6fb2c
fix(pi): align the plugin loopback check with the shared transport co…
larry-zy Aug 25, 2026
5d255df
fix(test): canonicalise the shared vectors JSON and de-flake the CLI …
larry-zy Aug 25, 2026
b33dcbe
fix(client): refuse all non-loopback plaintext unless the caller vouc…
larry-zy Aug 26, 2026
e3f1593
Merge upstream/master into fix/1319-transport-policy
larry-zy Aug 26, 2026
bc6009a
fix(bub): let the operator vouch for a controlled non-loopback transport
larry-zy Aug 26, 2026
d508b68
Merge remote-tracking branch 'upstream/master' into fix/1319-transpor…
larry-zy Aug 26, 2026
a40dd27
fix(langchain): align the merged integrations with the transport-trus…
larry-zy Aug 26, 2026
142c243
fix(bub): route the memory tools through the operator transport vouch
larry-zy Aug 26, 2026
be01f13
docs(config): state that the client refuses all plaintext non-loopbac…
larry-zy Aug 26, 2026
e18883e
chore: retrigger CI after GitHub runner outage
larry-zy Aug 26, 2026
aa42393
docs: state the full 127.0.0.0/8 loopback range and fix a heading sep…
larry-zy Aug 26, 2026
ea1688e
feat: add local portable archive CLI
larry-zy Sep 10, 2026
3c0e6fb
feat: add portable archive export and restore
larry-zy Sep 10, 2026
bffe534
test: normalize archive CLI help output
larry-zy Sep 12, 2026
62a73bb
fix(archive): validate wire records and rebuild complete projections
larry-zy Sep 19, 2026
6abf61e
merge: sync portable archive branch with upstream master
larry-zy Sep 20, 2026
a2f1032
merge: reconcile portable archive branch and fix regressions
larry-zy Sep 20, 2026
9f10299
refactor(archive): remove redundant code and unrelated changes
larry-zy Sep 20, 2026
7658ee3
fix(archive): pin export snapshots and preserve remote sources
larry-zy Sep 21, 2026
e386143
test(archive): cover remote source roundtrips across backends
larry-zy Sep 21, 2026
d269b75
refactor(archive): consolidate validation passes and family support
larry-zy Sep 21, 2026
9d09a06
Merge remote-tracking branch 'upstream/master' into feat/1421-portabl…
larry-zy Sep 22, 2026
fbdd194
fix(archive): preserve frozen recurrence decisions and events
larry-zy Sep 22, 2026
cffc9ca
Merge remote-tracking branch 'upstream/master' into feat/1421-portabl…
larry-zy Sep 29, 2026
f942131
fix(archive): validate content and identities before restore
larry-zy Sep 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/en/docs/operate/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Start with the operational task you need:
| --- | --- |
| Keep a personal Server running, deploy a container, or enable authentication | [Deploy the Server](deploy-server.md) |
| Upgrade or switch background supervision mode | [Migrate Artifact processing state](artifact-processing-migration.md) |
| Export a local SQLite archive or restore one | [Portable archive](portable-archive.md) |
| Inspect logs, metrics, and traces | [Observability](observability.md) |
| Send traces to an analysis service | [Phoenix](trace-with-phoenix.md), [Langfuse](trace-with-langfuse.md) |
| Diagnose failures and restore service or data | [Troubleshoot](troubleshoot.md) |
Expand Down
1 change: 1 addition & 0 deletions docs/en/docs/operate/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"deploy-server",
"connect-remote-server",
"artifact-processing-migration",
"portable-archive",
"observability",
"trace-with-phoenix",
"trace-with-langfuse",
Expand Down
171 changes: 171 additions & 0 deletions docs/en/docs/operate/portable-archive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
---
title: Export and restore a portable archive
description: Create, validate, and restore a verified PowerContext logical bundle.
---

# Export and restore a portable archive

A portable archive is a `.pcb` file for moving or recovering complete PowerContext scopes. It is a logical archive:
it preserves domain identities and immutable history rather than copying a SQLite file. Use it for a controlled local
backup, an offline transfer, or a future backend migration.

This is an offline operator command. It does not call a remote Server API. Without `--env-file` it opens the default
SQLite database; with `--env-file` it uses the same SQLite, SeekDB, or OceanBase settings as that deployment. Stop
PowerContext writers before restore. Export uses one database transaction as its consistent logical snapshot.
MySQL-mode backends use `REPEATABLE READ` for the export transaction even when the deployment defaults to
`READ COMMITTED`; later transactions retain the deployment default.

## Prerequisites

Install the CLI from the same PowerContext revision that created the local data. The archive command uses the persistent
SQLite database at `POWERCONTEXT_HOME/powercontext.db`; without `POWERCONTEXT_HOME`, PowerContext uses its operating
system user-data directory.

```bash
uv tool install "powercontext[cli] @ git+https://github.com/oceanbase/powercontext.git@master"
export POWERCONTEXT_HOME="$HOME/.local/share/powercontext"
```

The archive contains content and metadata needed for recovery. Store it in a protected location with access controls
and retention appropriate for the underlying project data. The format deliberately omits credentials and configured
provider secrets, but it does not encrypt the project content.

## Create and inspect an archive

Pass every complete scope to include. A scope cannot be selected by prefix or partially by record type.

```bash
powercontext archive export \
--scope-id project:payments \
--output ./backups/payments.pcb

powercontext archive inspect ./backups/payments.pcb
```

Add `--no-compress` when the surrounding storage system already compresses objects. Export authorization occurs before
the first database query. For this offline command, authority is the operating-system and database permission needed to
read the configured deployment; it never reuses or exports Server bearer tokens. Progress is emitted as content-free
JSON on stderr while the final receipt remains JSON on stdout.

`export` writes JSON containing the bundle ID, record count, and checksum. `inspect` verifies the ZIP structure,
per-record digests, total digest, record counts, and selected scopes without opening the target database. Keep the
reported checksum with the backup inventory if an external backup system needs an independent verification record.
Before publishing the file, export checks its format, resource limits, and dependencies. If validation fails, an
existing backup at the output path remains unchanged.

## Validate before a restore

Always validate the archive against the destination first:

```bash
powercontext archive restore ./backups/payments.pcb --dry-run
```

Dry-run performs no domain writes. It verifies checksums, required source and Artifact dependencies, and whether the
configured Runtime can restore the archive's source types and Artifact families. A validation failure exits with code
`2` for an invalid bundle, or `3` for unsupported requirements or target conflicts, and reports only a content-free
reason; record bodies are not printed. A successful report includes
`already_present`, `conflicts`, required and unsupported Source types and Artifact families, and whether the target has
a projection rebuilder. Run against a different deployment with `--env-file ./target.env`.

Native Sources require their Python adapter on the target. Worker-materialized `SourceObservation` records carry
their captured payload and projections, so they can be read without loading that adapter. The bundle includes only
the definition manifests referenced by the selected scopes and verifies observation identities and definition
fingerprints before restore. Missing definitions and conflicting target definitions prevent restoration; unreferenced
global definitions are not exported.

To perform the write, repeat the command with explicit confirmation:

```bash
powercontext archive restore ./backups/payments.pcb --yes
```

The result is JSON with `inserted`, `already_present`, and `projections_ready`. Treat the restore as ready for search
only when `projections_ready` is `true`. The Runtime rebuilds Memory, Topic Memory, and Experience search projections
after the authoritative rows have been restored, including configured Memory and Topic Memory vectors.

## What the bundle preserves

Format version 1 carries the portable relational representation of these supported records:

| Preserved | Not portable |
| --- | --- |
| Scope identity, hierarchy, context/external references, and creation identity | Scope access bindings and host-local default selection |
| Source journal heads, Source records, and referenced remote Source Definition manifests | Search projections and indexes |
| Artifact Revisions, lineage, cross-Scope publication provenance, and heads | Source cursors and scheduler state |
| Memory entry versions and heads | External Skill registrations and host-local installation state |
| Candidate versions, decision heads, and their evidence references | Audit events, usage facts, evaluation receipts, and restore receipts |
| Managed Skill package bytes and manifests; Artifact and Memory-entry tags | Download locations and host-local Skill paths |
| Profile policies, Prompt revisions, and Topic Memory publication metadata | Target-specific embedding configuration |
| Work contracts, task outcomes, Handoff boundaries and receipts stored as Sources | Credentials, bearer tokens, provider secrets, and host-local Skill installation state |

The archive has a versioned manifest (`format_version`, producer version, scopes, counts, exclusions, and total
checksum) plus NDJSON records. It is the authoritative round-trip format. CSV may be produced separately for bounded
analysis, but it cannot preserve immutable revisions, lineage, or evidence references and must not be used for restore.

Frozen recurrence matches and events are preserved with their original idempotency keys, Source positions, and exact
Artifact revisions. Restore validates candidate revisions, Handoff/receipt references, and event-to-match dependencies.
Advancing an Experience head does not change this history; replay after restore reuses the saved decisions.

## Recovery and conflicts

Restore is idempotent. Replaying the same archive recognizes identical records as `already_present`. A different
payload for an existing immutable identity never overwrites it: restore exits with code `3` and leaves the write
transaction rolled back. Resolve the conflicting target data or choose a clean destination, then run the same restore
command again.

If the command is interrupted before completion, do not claim recovery succeeded. Authoritative records are
transactionally applied, so a failed write does not leave a successful-looking partial restore. Re-run the same archive
against the same destination after the previous command has stopped.

The target database stores a durable receipt keyed by `bundle_id`. `authoritative_restored` means the logical rows
committed but search rebuild has not completed; `ready` means projection rebuild completed. If projection rebuild
fails, re-run the same restore: identical rows are skipped and the receipt advances to `ready` only after verification.
The restore command can reopen unfinished Topic Memory projections when a pending restore receipt exists. Normal
Server startup still rejects incomplete projections; finish the restore before serving requests. Use the same target
embedding configuration when retrying.

Restore stages records in a temporary disk index before starting the target write transaction. Reserve temporary
disk space for both the archive copy and its expanded records. Existing MySQL-mode deployments may require an
explicit Runtime startup schema upgrade from `DATETIME` to `DATETIME(6)` for portable timestamps; back up the database
and provide schema-alter permissions before that upgrade.

## SQLite to OceanBase migration

Create separate environment files without placing credentials in the bundle:

```bash
powercontext archive export --env-file ./sqlite.env \
--scope-id project:payments --output ./payments.pcb
powercontext archive restore ./payments.pcb --env-file ./oceanbase.env --dry-run
powercontext archive restore ./payments.pcb --env-file ./oceanbase.env --yes
```

The environment files use `POWERCONTEXT_SERVER_DATABASE_KIND` and `POWERCONTEXT_SERVER_DATABASE_URL` as documented in
the Server configuration guide. Dry-run must report no unsupported families and zero conflicts before the write.

## Format compatibility

Format version `1` readers require support for every record type present in the bundle. Older readers may reject
new record types even when the bundle uses format version `1`. The producer version is reported for diagnostics but
does not replace the archive schema version or record-type compatibility checks. Writers produce only version `1`; there is no
format `0` downgrade. A reader rejects unknown archive or record schema versions before target writes. Keep the old
binary available until a restore drill succeeds when upgrading across a PowerContext major release.

## Deployment-native backups

Logical export is not a substitute for a crash-consistent deployment backup:

- SQLite: stop all PowerContext writers before copying the database, or use the SQLite online backup API, for example
`sqlite3 powercontext.db ".backup './backups/powercontext.db'"`. Verify the copy with
`sqlite3 ./backups/powercontext.db "PRAGMA integrity_check"`, protect it like the source database, and test reopening it.
- OceanBase: enable tenant data backup and log archiving according to the deployed OceanBase version, retain the backup
destination and encryption material independently, and perform a restore drill into an isolated tenant. Use native
backup for point-in-time recovery and the portable bundle for logical cross-backend migration.

## Current boundaries

Export streams database rows to a temporary NDJSON file. Validation stores only record identities in a temporary
on-disk index, and restore replays dependency levels as streams, so aggregate archive payloads are not retained in
process memory. Scope metadata is bounded by the manifest scope list. The command is not a remote Server API and never
puts deployment configuration or database credentials into the archive.
2 changes: 1 addition & 1 deletion docs/en/docs/operate/troubleshoot.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ so the previous database remains available for recovery:

```bash
obloader <connection-options> -D <new-database> --csv \
--table 'pc_scopes,pc_source_journal_heads,pc_sources,pc_artifacts,pc_source_cursors,pc_artifact_processing_leases,pc_artifact_processing_binding_states,pc_artifact_processing_pending,pc_artifact_processing_auto_wave_targets,pc_artifact_processing_sequences,pc_artifact_processing_intents,pc_topic_memory_processing_targets,pc_artifact_processing_schema,pc_artifact_processing_migration_receipts,pc_topic_memory_work_budgets,pc_topic_memory_retrieval_shape,pc_connector_checkpoints,pc_source_definition_manifests,pc_external_skill_registrations,pc_skill_packages,pc_agent_skill_targets,pc_skill_publications,pc_model_usage_daily,pc_recall_token_daily,pc_receipt_migration_review' \
--table 'pc_scopes,pc_source_journal_heads,pc_sources,pc_artifacts,pc_portable_restore_receipts,pc_source_cursors,pc_artifact_processing_leases,pc_artifact_processing_binding_states,pc_artifact_processing_pending,pc_artifact_processing_auto_wave_targets,pc_artifact_processing_sequences,pc_artifact_processing_intents,pc_topic_memory_processing_targets,pc_artifact_processing_schema,pc_artifact_processing_migration_receipts,pc_topic_memory_work_budgets,pc_topic_memory_retrieval_shape,pc_connector_checkpoints,pc_source_definition_manifests,pc_external_skill_registrations,pc_skill_packages,pc_agent_skill_targets,pc_skill_publications,pc_model_usage_daily,pc_recall_token_daily,pc_receipt_migration_review' \
-f <export-directory>
```

Expand Down
1 change: 1 addition & 0 deletions docs/zh/docs/operate/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ description: 持续运行 Server,查找部署、监控与恢复步骤。
| --- | --- |
| 持续运行个人 Server、部署容器或启用认证 | [部署 Server](deploy-server.md) |
| 升级或切换后台监督模式 | [迁移 Artifact 处理状态](artifact-processing-migration.md) |
| 导出本地 SQLite 归档或恢复归档 | [可移植归档](portable-archive.md) |
| 查看日志、指标和 Trace | [可观测性](observability.md) |
| 将 Trace 发送到分析服务 | [Phoenix](trace-with-phoenix.md)、[Langfuse](trace-with-langfuse.md) |
| 诊断失败并恢复服务或数据 | [诊断与恢复](troubleshoot.md) |
Expand Down
1 change: 1 addition & 0 deletions docs/zh/docs/operate/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"deploy-server",
"connect-remote-server",
"artifact-processing-migration",
"portable-archive",
"observability",
"trace-with-phoenix",
"trace-with-langfuse",
Expand Down
Loading
Loading