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 docs/features/codex-prompt-center.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ The catalog is intentionally broader than the editor. Context Room discovers gro

- **Editable here**: the runtime publishes an official baseline, an effective value, `editable: true`, `securityClass: local_user_editable`, an allowed editable runtime status, and one coherent override strategy. Only model-base, developer, local compaction, and selectable collaboration targets can enter this class.
- **Configurable elsewhere**: another local Codex configuration or task-history surface owns the value. Prompt Center shows the owner and read-only reason instead of competing with it.
- **Protected**: security-, protocol-, enforcement-, lifecycle-, or platform-coupled instructions are metadata-only. Prompt text and hashes are not published to Context Room.
- **Protected**: security-, protocol-, enforcement-, lifecycle-, platform-, or client-owned instructions are metadata-only. Prompt text and hashes are not published to Context Room.
- **Server-owned**: a remote service owns the instruction. The target is metadata-only and cannot be replaced locally.

The platform-supplied system prompt and remote/server compaction instructions cannot be read or replaced through this local integration. Prompt Center shows only their metadata and read-only reason. This boundary is enforced by both the JSON catalog contract and Context Room's runtime checks; a forged `editable: true` flag is rejected.
Expand Down
7 changes: 5 additions & 2 deletions schemas/codex-prompt-catalog-v1.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@
"history_semantics",
"executable_contract",
"configurable_elsewhere",
"client_owned",
"server_owned"
]
}
Expand Down Expand Up @@ -471,7 +472,8 @@
"lifecycle_managed",
"history_semantics",
"executable_contract",
"configurable_elsewhere"
"configurable_elsewhere",
"client_owned"
]
}
},
Expand Down Expand Up @@ -534,7 +536,8 @@
"lifecycle_managed",
"history_semantics",
"executable_contract",
"configurable_elsewhere"
"configurable_elsewhere",
"client_owned"
]
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/codex_prompt_center.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ const CATALOG_SECURITY_CLASSES = new Set([
"history_semantics",
"executable_contract",
"configurable_elsewhere",
"client_owned",
"server_owned",
]);
const CATALOG_OVERRIDE_CONFLICT_CODES = new Set([
Expand Down Expand Up @@ -267,6 +268,7 @@ const PROTECTED_SECURITY_CLASSES = new Set([
"history_semantics",
"executable_contract",
"configurable_elsewhere",
"client_owned",
]);
function promptCenterError(message, statusCode = 400, code = "codex_prompt_request_failed", details = undefined) {
const error = new Error(message);
Expand Down
14 changes: 14 additions & 0 deletions test/codex_prompt_center.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ test("durable JSON schemas match the strict Rust catalog, manifest, publication
"history_semantics",
"executable_contract",
"configurable_elsewhere",
"client_owned",
"server_owned",
]);
assert.deepEqual(catalogSchema.$defs.overrideConflict.properties.code.enum, [
Expand Down Expand Up @@ -1008,6 +1009,19 @@ test("catalog authority classes, effective content, and editable strategy fail c
assert.equal(validProtected.official, null);
assert.equal(validProtected.effective, null);

const clientOwnedCatalog = fixtureCatalog();
const clientOwnedTarget = clientOwnedCatalog.groups[1].targets[0];
clientOwnedTarget.id = "protected/client/tui_init";
clientOwnedTarget.label = "TUI /init command prompt";
clientOwnedTarget.securityClass = "client_owned";
const clientOwned = createCodexPromptCenterProvider({
storageRoot: makeStorage(t),
catalog: clientOwnedCatalog,
}).readTarget(clientOwnedTarget.id);
assert.equal(clientOwned.kind, "protected");
assert.equal(clientOwned.editable, false);
assert.equal(clientOwned.securityClass, "client_owned");

const serverOwnedCatalog = fixtureCatalog();
serverOwnedCatalog.groups[1].targets[0] = strictCatalogTarget({
id: "synthetic/server/owned",
Expand Down
Loading