Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"name": "powercontext",
"source": "./integrations/claude-code/plugins/powercontext",
"description": "Restore project memory and transfer current work from Claude Code",
"version": "0.1.2",
"version": "0.1.3",
"category": "Productivity"
}
]
Expand Down
2 changes: 1 addition & 1 deletion desktop/src-tauri/src/transport/operations.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"contractSha256": "5c00096f12642263d6bc538f7271a1484e1f8a17660786b12563cac9f4d6b0ab",
"contractSha256": "7e1c301bf7f2ac51781280959efd0b2d92511ddeadee8314ba1683d956c93cc7",
"operations": {
"get_liveness": {
"method": "GET",
Expand Down
160 changes: 160 additions & 0 deletions desktop/ui/src/generated/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,46 @@ export interface paths {
patch?: never;
trace?: never;
};
"/v1/context/bootstrap": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* Prepare bounded context for an Agent lifecycle boundary
* @description Prepare an opt-in, deterministic bootstrap package without manufacturing a query. Only explicitly curated active Atomic Memory Artifacts and one caller-selected exact committed Handoff are eligible. Returned historical text is untrusted data and grants no authority. A ready receipt remains pending until the host records delivery. Reusing one stable event identity with different package-shaping fields is rejected with 422.
*/
post: operations["prepare_bootstrap_context"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/v1/context/bootstrap/receipts": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* Record a bootstrap delivery outcome
* @description Atomically claim one pending content-free receipt as injected or failed. A second injected claim is rejected with 422, so concurrent lifecycle hooks cannot both inject the same package. A terminal outcome never changes.
*/
post: operations["record_bootstrap_delivery"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/v1/work/contracts/create": {
parameters: {
query?: never;
Expand Down Expand Up @@ -3282,6 +3322,29 @@ export interface components {
content: string | null;
content_bytes: number;
};
BootstrapContextItem: {
kind: components["schemas"]["BootstrapContextItemKind"];
scope_id: string;
artifact: components["schemas"]["ArtifactReference"];
content_digest: string;
truncated: boolean;
};
BootstrapDeliveryReceipt: {
receipt_id: string;
state: components["schemas"]["BootstrapReceiptState"];
};
BootstrapContext: {
schema: components["schemas"]["BootstrapContextSchema"];
status: components["schemas"]["BootstrapContextStatus"];
reason: components["schemas"]["BootstrapSkipReason"] | null;
profile: components["schemas"]["BootstrapContextProfile"];
content: string | null;
content_bytes: number;
package_digest: string | null;
items: components["schemas"]["BootstrapContextItem"][];
truncated: boolean;
receipt: components["schemas"]["BootstrapDeliveryReceipt"];
};
EntryChange: {
op: components["schemas"]["EntryChangeOperation"];
entry_id: string;
Expand Down Expand Up @@ -3959,6 +4022,29 @@ export interface components {
*/
include_code: boolean;
assembly?: components["schemas"]["ContextAssembly"];
/** @description Optional exact receipt for the last successfully injected bootstrap package. Only fully delivered Atomic Memory revisions from an injected same-Scope receipt are removed before candidate limiting and sufficiency assessment; Artifacts whose bootstrap bodies were truncated remain eligible. */
bootstrap_receipt_id?: string;
};
BootstrapContextRequest: {
scope_id: string;
/** @default false */
enabled: boolean;
/** @default powercontext.scope-bootstrap.v1 */
profile: components["schemas"]["BootstrapContextProfile"];
lifecycle: components["schemas"]["BootstrapContextLifecycle"];
integration: string;
/** @description Optional stable host event identity, persisted only as a digest. Within the same Scope, integration, and lifecycle, retries must keep the profile, max_bytes, and exact Handoff unchanged. */
event_id?: string;
/** @default 4096 */
max_bytes: number;
/** @description Optional exact committed Handoff Revision in the current Scope. */
handoff?: components["schemas"]["ArtifactReference"];
};
RecordBootstrapDeliveryRequest: {
scope_id: string;
receipt_id: string;
/** @enum {string} */
outcome: "injected" | "failed";
};
ContextAssemblySection: {
family: components["schemas"]["ContextAssemblyFamily"];
Expand Down Expand Up @@ -4512,6 +4598,20 @@ export interface components {
/** @enum {string} */
PreparedContextStatus: "ready" | "empty";
/** @enum {string} */
BootstrapContextSchema: "powercontext.bootstrap-context.v1";
/** @enum {string} */
BootstrapContextProfile: "powercontext.scope-bootstrap.v1";
/** @enum {string} */
BootstrapContextLifecycle: "startup" | "resume" | "clear" | "compact" | "restore" | "fork";
/** @enum {string} */
BootstrapContextStatus: "ready" | "empty" | "skipped";
/** @enum {string} */
BootstrapContextItemKind: "atomic-memory" | "handoff";
/** @enum {string} */
BootstrapReceiptState: "pending" | "injected" | "skipped" | "failed";
/** @enum {string} */
BootstrapSkipReason: "disabled" | "no_eligible_context" | "already_delivered" | "preparation_failed";
/** @enum {string} */
EntryChangeOperation: "add" | "revise" | "deactivate" | "reactivate" | "compact";
/** @enum {string} */
FlushStatus: "idle" | "processed";
Expand Down Expand Up @@ -5929,6 +6029,66 @@ export interface operations {
503: components["responses"]["Unavailable"];
};
};
prepare_bootstrap_context: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["BootstrapContextRequest"];
};
};
responses: {
/** @description A bounded package ready for host injection, or a normal empty/skipped result. */
200: {
headers: {
"X-PowerContext-Request-ID": components["headers"]["RequestId"];
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["BootstrapContext"];
};
};
401: components["responses"]["Unauthorized"];
403: components["responses"]["Forbidden"];
404: components["responses"]["NotFound"];
422: components["responses"]["InvalidRequest"];
500: components["responses"]["InternalError"];
503: components["responses"]["Unavailable"];
};
};
record_bootstrap_delivery: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["RecordBootstrapDeliveryRequest"];
};
};
responses: {
/** @description Current durable delivery state. */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["BootstrapDeliveryReceipt"];
};
};
401: components["responses"]["Unauthorized"];
403: components["responses"]["Forbidden"];
422: components["responses"]["InvalidRequest"];
500: components["responses"]["InternalError"];
503: components["responses"]["Unavailable"];
};
};
create_work_contract: {
parameters: {
query?: never;
Expand Down
2 changes: 1 addition & 1 deletion desktop/ui/src/generated/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

// Generated from openapi/powercontext.yaml. Do not edit.
export const contractSha256 = "5c00096f12642263d6bc538f7271a1484e1f8a17660786b12563cac9f4d6b0ab";
export const contractSha256 = "7e1c301bf7f2ac51781280959efd0b2d92511ddeadee8314ba1683d956c93cc7";
export const operations = {
"get_liveness": {
"method": "GET",
Expand Down
33 changes: 32 additions & 1 deletion docs/en/docs/integrations/claude-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ powercontext doctor claude-code
claude
```

Use `/hooks` to confirm the `UserPromptSubmit` Hook and `/mcp` to confirm the `powercontext` Server.
Use `/hooks` to confirm the `SessionStart` and `UserPromptSubmit` Hooks and `/mcp` to confirm the `powercontext` Server.
These are separate capture/recall and explicit-tool connections; both must work. `doctor claude-code` primarily checks
installation state. Complete the [Source and Topic check](../get-started/quickstart.md#4-verify-topic-memory-with-ordinary-conversation) to verify memory behavior.

Expand All @@ -82,6 +82,34 @@ For each user prompt, the Hook:
3. strictly validates `powercontext.prepared-context.v1` and injects it unchanged through `additionalContext`;
4. independently captures the prompt as ordinary Content Source evidence.

Bootstrap context is a separate, opt-in `SessionStart` path. Enable it before launching Claude Code:

```bash
export POWERCONTEXT_CLAUDE_BOOTSTRAP_CONTEXT=true
claude
```

On `startup`, `resume`, `clear`, `compact`, and `fork`, the fixed `powercontext.scope-bootstrap.v1` profile can inject
at most six active Atomic Memory Artifacts explicitly tagged `bootstrap-context`, considering the current Scope before
at most eight direct Context References. It never scans all Memory, Sources, transcripts, pending Candidates, or
generated instructions; secret-like Memory kinds are excluded. The content is untrusted history and cannot override
current instructions.

The default 4096-byte budget can be set from 512 through 8192 bytes with
`POWERCONTEXT_CLAUDE_BOOTSTRAP_MAX_BYTES`. No Handoff is selected automatically. Select one exact committed Handoff
from the current Scope only when it is intended for the new Session:

```bash
export POWERCONTEXT_CLAUDE_BOOTSTRAP_HANDOFF='{"artifact_id":"HANDOFF_ID","revision":3}'
```

Use the Atomic Memory Artifact tag API to add `bootstrap-context` only to reviewed decisions, constraints, objectives,
verified state, or repository guidance. The plugin stores a content-free receipt under `${CLAUDE_PLUGIN_DATA}`;
successful delivery lets the first ordinary query suppress only fully delivered exact Atomic Memory revisions.
Artifacts truncated during bootstrap and newer revisions remain eligible. Preparation, validation, and receipt failures
fail open and inject nothing. Failures before a new lifecycle package is established, including invalid configuration,
also clear any stale saved receipt.

The Source pipeline may later extract Memory when a generation model is configured. Prompt capture does not call
`remember_memory`, and the Hook never labels an ordinary prompt as `task-outcome`.

Expand Down Expand Up @@ -222,6 +250,9 @@ run with `--keep-data`.
| `POWERCONTEXT_CLAUDE_ALLOW_INSECURE_HTTP` | `false` | Explicitly permit non-loopback plaintext HTTP for PowerContext requests |
| `POWERCONTEXT_CLAUDE_SCOPE_ID` | unset | Override durable bindings and the Server default Scope |
| `POWERCONTEXT_CLAUDE_AUTHORIZATION` | unset | Complete `Bearer <token>` header for Hook and MCP requests |
| `POWERCONTEXT_CLAUDE_BOOTSTRAP_CONTEXT` | `false` | Inject the curated bootstrap profile on supported `SessionStart` events |
| `POWERCONTEXT_CLAUDE_BOOTSTRAP_MAX_BYTES` | `4096` | Bootstrap package limit; valid values are 512 through 8192 bytes |
| `POWERCONTEXT_CLAUDE_BOOTSTRAP_HANDOFF` | unset | JSON identity of one exact committed Handoff, for example `{"artifact_id":"...","revision":3}` |
| `POWERCONTEXT_CLAUDE_CAPTURE_PROMPTS` | `true` | Capture user prompts as ordinary Source evidence |
| `POWERCONTEXT_CLAUDE_FLUSH_ON_CAPTURE` | `false` | Wait for Source processing after capture |
| `POWERCONTEXT_CLAUDE_REQUEST_TIMEOUT_SECONDS` | `3` | Per-request Hook timeout |
Expand Down
42 changes: 41 additions & 1 deletion docs/en/docs/integrations/codex.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Conflicting file and process declarations still require an explicit choice; use
runtime URL overrides before rerunning setup. `--source` selects plugin code, not the Server endpoint.

Open a new Codex session after setup. Use `/hooks` to inspect and, when prompted, trust the PowerContext
`UserPromptSubmit` hook.
`SessionStart` and `UserPromptSubmit` hooks.

`powercontext doctor codex --json` reports basic MCP connectivity as `mcp_tools` and complete tool coverage as
`mcp_full_profile`. Full coverage requires every capability-bearing tool in the Codex integration's `server-mcp`
Expand Down Expand Up @@ -101,6 +101,43 @@ another task, session, or model. It must be explicitly prepared, inspected, and
a few Memory entries. Read [Memory and Handoff](../workflows/memory-and-handoff.md) for the boundary and
[Hand off work in Codex](../workflows/handoff-with-codex.md) for the procedure.

## Opt in to Session bootstrap context

Bootstrap context is off by default. To load a small, deterministic package before Codex's first prompt on
`startup`, `resume`, `clear`, or `compact`, start Codex with:

```bash
export POWERCONTEXT_CODEX_BOOTSTRAP_CONTEXT=true
codex
```

The fixed `powercontext.scope-bootstrap.v1` profile includes at most six active Atomic Memory Artifacts explicitly
tagged `bootstrap-context`, considering the current Scope before at most eight direct Context References. It never
scans all Memory, Sources, transcripts, pending Candidates, or generated instructions. Secret-like Memory kinds are
excluded. Historical text is marked as untrusted and cannot override current user, developer, system, or repository
instructions.

The default package limit is 4096 UTF-8 bytes. It can be set from 512 through 8192 bytes:

```bash
export POWERCONTEXT_CODEX_BOOTSTRAP_MAX_BYTES=6144
```

No Handoff is selected automatically. To add one exact committed Handoff from the current Scope, provide its immutable
identity before starting Codex:

```bash
export POWERCONTEXT_CODEX_BOOTSTRAP_HANDOFF='{"artifact_id":"HANDOFF_ID","revision":3}'
```

Use the Atomic Memory Artifact tag API to add `bootstrap-context` only to reviewed decisions, constraints, objectives,
verified state, or repository guidance suitable for every new Session. A content-free delivery receipt makes retries
idempotent; after successful injection, the first ordinary query sends that receipt so the Runtime suppresses only
fully delivered exact Atomic Memory revisions. Artifacts truncated during bootstrap and newer revisions remain eligible
for recall.
Preparation, validation, and receipt failures all fail open and inject nothing.
Failures before a new lifecycle package is established, including invalid configuration, also clear any stale saved receipt.

## Experience and Skill

Alongside Memory, Source capture, context injection,
Expand Down Expand Up @@ -286,6 +323,9 @@ Complete the [Source, topic evolution, and cross-session recall check](../get-st
| `POWERCONTEXT_CODEX_ALLOW_INSECURE_HTTP` | `false` | Explicitly permit non-loopback plaintext HTTP for hooks |
| `POWERCONTEXT_CODEX_SCOPE_ID` | unset | Explicitly select an existing Scope instead of resolving bindings and the Server default |
| `POWERCONTEXT_CODEX_AUTHORIZATION` | unset | Complete `Bearer <token>` runtime override; setup saves it for subsequent Hook and native MCP connections |
| `POWERCONTEXT_CODEX_BOOTSTRAP_CONTEXT` | `false` | Inject the curated bootstrap profile on supported `SessionStart` events |
| `POWERCONTEXT_CODEX_BOOTSTRAP_MAX_BYTES` | `4096` | Bootstrap package limit; valid values are 512 through 8192 bytes |
| `POWERCONTEXT_CODEX_BOOTSTRAP_HANDOFF` | unset | JSON identity of one exact committed Handoff, for example `{"artifact_id":"...","revision":3}` |
| `POWERCONTEXT_CODEX_CAPTURE_PROMPTS` | `true` | Capture user prompts as Source evidence |
| `POWERCONTEXT_CODEX_FLUSH_ON_CAPTURE` | `false` | Wait for Source processing after capture |
| `POWERCONTEXT_CODEX_REQUEST_TIMEOUT_SECONDS` | `3` | Per-request hook timeout |
Expand Down
5 changes: 3 additions & 2 deletions docs/en/docs/operate/troubleshoot.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,8 @@ so the previous database remains available for recovery:
exported `pc_scopes` data.
If the source predates the three Skill lifecycle tables (`pc_skill_packages`, `pc_agent_skill_targets`, and
`pc_skill_publications`), the Profile tables, `pc_topic_memory_work_budgets`, `pc_recall_effort_daily`,
`pc_receipt_migration_review`, or `pc_decision_observations`, remove the absent tables from their respective layers.
`pc_receipt_migration_review`, `pc_context_bootstrap_receipts`, or `pc_decision_observations`, remove the absent
tables from their respective layers.
When a work-budget table exists, restore it together with Cursors so failure allowances survive the migration.

Layer 1 contains parents and tables without foreign keys:
Expand All @@ -275,7 +276,7 @@ so the previous database remains available for recovery:

```bash
obloader <connection-options> -D <new-database> --csv \
--table 'pc_dream_runs,pc_scope_context_references,pc_scope_external_references,pc_scope_creation_requests,pc_scope_settings,pc_scope_bindings,pc_artifact_heads,pc_artifact_lineage_sources,pc_artifact_lineage_artifacts,pc_artifact_publications,pc_artifact_candidate_versions,pc_topic_memory_revision_publications,pc_memory_entry_versions' \
--table 'pc_dream_runs,pc_context_bootstrap_receipts,pc_scope_context_references,pc_scope_external_references,pc_scope_creation_requests,pc_scope_settings,pc_scope_bindings,pc_artifact_heads,pc_artifact_lineage_sources,pc_artifact_lineage_artifacts,pc_artifact_publications,pc_artifact_candidate_versions,pc_topic_memory_revision_publications,pc_memory_entry_versions' \
-f <export-directory>
```

Expand Down
Loading
Loading