Skip to content
Open
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 desktop/src-tauri/src/transport/operations.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"contractSha256": "9f4ba7b35ecd3b3639af4e648aff84b713a7f30b51d5a4c30c8809aeb8dc8024",
"contractSha256": "0df92a02d48ab6380983b92d03c2cea02444ede7429b96b09865bd94b35d71f0",
"operations": {
"get_liveness": {
"method": "GET",
Expand Down
34 changes: 32 additions & 2 deletions desktop/ui/src/generated/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1669,7 +1669,7 @@ export interface paths {
get: operations["get_artifact"];
/**
* Replace the current Artifact head
* @description Commit a complete next revision when If-Match identifies the current head. Replacing a Prompt requires current scope.admin authority, including switching to Auto and restoring an earlier revision. Artifact ownership does not authorize Prompt replacement after Scope role revocation. Topic Memory replacement also requires scope.admin and preserves independently versioned tags. Complete title, summary, and detail text replaces the head without semantic generation.
* @description Commit a complete next revision when If-Match identifies the current head. Replacing a Prompt requires current scope.admin authority, including switching to Auto and restoring an earlier revision. Artifact ownership does not authorize Prompt replacement after Scope role revocation. Topic Memory replacement also requires scope.admin and preserves independently versioned tags. Complete title, summary, and detail text replaces the head without semantic generation. Profile replacement uses the same conditional write. To roll back Profile, Prompt, Experience, Skill, Handoff, or Topic Memory, set restored_from_revision and reason. The server checks that the submitted canonical content matches that revision and differs from the current head, then commits a new revision. Memory replacement cannot restore a whole historical manifest.
*/
put: operations["replace_artifact"];
post?: never;
Expand Down Expand Up @@ -2064,6 +2064,10 @@ export interface components {
};
ReplaceProfileArtifactRequest: {
content: components["schemas"]["ProfileWriteContent"];
/** @description Historical Profile revision restored by this replacement. Must match content.restored_from_revision when both are set. */
restored_from_revision?: number | null;
/** @description Required when restored_from_revision or content.restored_from_revision is set. */
reason?: string | null;
};
ActivateHandoffRequest: {
scope_id: string;
Expand Down Expand Up @@ -2093,6 +2097,11 @@ export interface components {
published_at?: string | null;
/** @description Family-provided number of direct Source inputs when available. */
source_count?: number | null;
/** Format: date-time */
created_at?: string | null;
created_by?: components["schemas"]["AccessPrincipal"] | null;
restored_from_revision?: number | null;
reason?: string | null;
};
ArtifactCreated: {
scope_id: string;
Expand Down Expand Up @@ -2123,6 +2132,17 @@ export interface components {
/** @default [] */
memory_citations: components["schemas"]["MemoryCitation"][];
content_digest: string;
/**
* Format: date-time
* @description When this revision was committed. Absent for revisions stored before this field existed.
*/
created_at?: string | null;
/** @description Principal that committed a rollback. Ordinary revisions omit it. */
created_by?: components["schemas"]["AccessPrincipal"] | null;
/** @description Historical revision restored by this rollback. */
restored_from_revision?: number | null;
/** @description Reason recorded for a rollback. */
reason?: string | null;
};
ArtifactReference: {
family: string;
Expand Down Expand Up @@ -3882,6 +3902,8 @@ export interface components {
};
ReplaceTopicMemoryArtifactRequest: {
content: components["schemas"]["TopicMemoryWriteContent"];
restored_from_revision?: number | null;
reason?: string | null;
};
CreatePromptArtifactRequest: {
/**
Expand Down Expand Up @@ -4023,6 +4045,8 @@ export interface components {
ReplaceArtifactRequest: components["schemas"]["ReplaceTopicMemoryArtifactRequest"] | components["schemas"]["ReplaceMemoryArtifactRequest"] | components["schemas"]["ReplaceExperienceArtifactRequest"] | components["schemas"]["ReplaceSkillArtifactRequest"] | components["schemas"]["ReplaceHandoffArtifactRequest"] | components["schemas"]["ReplacePromptArtifactRequest"] | components["schemas"]["ReplaceProfileArtifactRequest"];
ReplacePromptArtifactRequest: {
content: components["schemas"]["PromptContent"];
restored_from_revision?: number | null;
reason?: string | null;
};
ListArtifactRevisionsRequest: {
/** @default 50 */
Expand Down Expand Up @@ -4123,12 +4147,18 @@ export interface components {
};
ReplaceExperienceArtifactRequest: {
content: components["schemas"]["ExperienceProposal"];
restored_from_revision?: number | null;
reason?: string | null;
};
ReplaceSkillArtifactRequest: {
content: components["schemas"]["SkillProposal"];
restored_from_revision?: number | null;
reason?: string | null;
};
ReplaceHandoffArtifactRequest: {
content: components["schemas"]["HandoffContent"];
restored_from_revision?: number | null;
reason?: string | null;
};
SourceRecord: {
/** @description Server-owned identity attestation when this Source contains an enforced-mode Handoff Receipt. */
Expand Down Expand Up @@ -7421,7 +7451,7 @@ export interface operations {
};
path: {
scope_id: string;
family: "memory" | "experience" | "skill" | "handoff" | "prompt" | "topic-memory";
family: "memory" | "experience" | "skill" | "handoff" | "prompt" | "topic-memory" | "profile";
artifact_id: string;
};
cookie?: 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 = "9f4ba7b35ecd3b3639af4e648aff84b713a7f30b51d5a4c30c8809aeb8dc8024";
export const contractSha256 = "0df92a02d48ab6380983b92d03c2cea02444ede7429b96b09865bd94b35d71f0";
export const operations = {
"get_liveness": {
"method": "GET",
Expand Down
2 changes: 1 addition & 1 deletion docs/en/development/dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The Dashboard is a content viewer for personal use and demonstrations, disabled

A user may open the Dashboard to check an agreement, find an experience relevant to a similar problem, or resume interrupted work. The page needs to make the current scope clear, help them find the relevant record, and provide access to source material when they need to check it.

The core experience for 1.0 is reading saved content. Memories, experiences, skills and handoffs can exist independently. A scope containing only memories should work normally, and an empty scope should still have a clear entry point and page structure. Existing tools and APIs handle generation, review and saving. Reading their results should not require generation configuration.
The core experience for 1.0 is reading saved content. Existing pages also list revision history, compare two revisions, and roll an exact stored revision forward through the same conditional replace the API already uses. Memory history is read-only because replacing a memory appends entries rather than restoring a snapshot. Memories, experiences, skills and handoffs can exist independently. A scope containing only memories should work normally, and an empty scope should still have a clear entry point and page structure. Existing tools and APIs handle generation, review and saving. Reading their results should not require generation configuration.

Scope names, summaries and saved content supply the business topic. A payment service, customer interviews and personal research can use the same interface without separate navigation for each domain. Before adding a section, explain which task it helps the user complete and whether the available data supports what it claims.

Expand Down
12 changes: 8 additions & 4 deletions docs/en/rfcs/1468_scope_owned_prompt_management.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,12 +267,15 @@ Rollback is deliberately not a history rewrite and does not require a third endp

1. read the old exact revision;
2. read the current head and ETag;
3. replace the current head with the old revision's `content` and the current ETag; and
3. replace the current head with the old revision's `content`, the current ETag, `restored_from_revision`, and a
non-blank `reason`; and
4. receive a new revision whose content digest matches the restored revision.

For example, restoring revision 2 while revision 5 is current creates revision 6. Revisions 2 through 5 remain
readable. Generic request audit identifies the actor and request; equality with the restored content is visible through
the content digest. The Server never moves the head pointer backward.
readable. The new revision stores the source revision, the reason, and the authenticated principal. Every new revision
stores `created_at`. Equality with the restored content is visible through the content digest. The Server never moves
the head pointer backward. Omitting both rollback fields remains an ordinary replace. Naming a source without a valid
reason, naming the current head, or submitting content that does not match that source returns 422.

# Reference-level explanation

Expand Down Expand Up @@ -815,7 +818,8 @@ as every update.
- **Draft, review, and activation workflows:** duplicate Candidate/Review concepts and are not needed for the first
administrative vertical slice.
- **A dedicated rollback endpoint:** adds an action whose safe semantics are already expressed by exact read plus
conditional replacement.
conditional replacement. The replace request may name the source revision and a reason; it does not add a route or
a permission.

Doing nothing leaves operational prompts fixed at deployment composition and forces customers to fork Runtime code or
run separate deployments for different prompt behavior.
Expand Down
15 changes: 9 additions & 6 deletions docs/en/rfcs/1485_profile_artifact.md
Original file line number Diff line number Diff line change
Expand Up @@ -428,17 +428,20 @@ ordinal=0, ETag/If-Match, and lineage rules. Create uses artifact_id=profile and
Automatic commits use the same Family validation and repository but cite actual evidence rather than inventing a
manual system Source.

Rollback needs no new API: GET a historical Revision, GET the current Head ETag, then PUT the complete Markdown with
optional `restored_from_revision` in ProfileWriteContent. The server verifies that the historical Revision exists
and its normalized Markdown matches, then creates a new rollback Revision. It neither moves Head back to an older
Revision nor rewinds the Cursor. Omitting the field is an ordinary manual Replace; Create forbids it. Clients compare
two Revisions themselves, with no new diff or history-list endpoint.
Rollback needs no new API: GET a historical Revision, GET the current Head ETag, then PUT the complete Markdown.
`restored_from_revision` may appear beside `content` and inside ProfileWriteContent; when both are set they are the
same integer. A source revision requires a non-blank `reason` of at most 1024 characters. The server verifies that the
historical Revision exists and its normalized Markdown matches, then creates a new rollback Revision that records the
source, the reason, and the authenticated principal. It neither moves Head back to an older Revision nor rewinds the
Cursor. Omitting both source fields is an ordinary manual Replace; Create forbids the source field. Clients compare
two Revisions themselves. The Dashboard renders that comparison; there is no separate diff endpoint.

## Persistence inventory and example rows

BLOB examples below show decoded JSON. Foreign keys and lineage use complete identities. Timestamps and digests
are readable examples; omitted default columns are still written according to existing definitions. Existing tables
have no DDL changes; only Profile BLOB schemas and code branches are extended.
keep their existing constraints. Artifact rows gain nullable `created_at`, `created_by`, `restored_from_revision`, and
`rollback_reason`. Profile BLOB schemas and code branches are extended as specified below.

```mermaid
erDiagram
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ New Handoff writes use a Scope singleton, while detail links can select historic
- Distinguish absent content, read errors, historical content, and failed downloads.
- Preserve collection return context and recover exact reading destinations after authentication.
- Preserve existing Prompt and Topic Memory routes, layouts, search, and pagination without duplicate entry points.
- Exclude profile editing, rollback, regeneration, review, and processing policy management.
- Exclude profile editing, regeneration, review, and processing policy management. History, comparison, and rollback of one exact stored revision stay on the existing page and reuse conditional replace.
- Exclude an all-artifacts browser, cross-Scope aggregation, batch downloads, PDF, public sharing, imports, and a new
machine-readable Agent handoff contract.

Expand Down Expand Up @@ -320,8 +320,8 @@ public selection and digest contract would broaden the feature, so use a Dashboa

Allowlisted relative destinations survive refreshes and copied links; browser history and Referer cannot reliably
distinguish normal navigation, direct entry, and authentication. Returning to exact detail after login preserves an
explicit download action. Profile editing, generation, and rollback require conditional writes, review, and conflict
recovery and remain available through existing tools and APIs.
explicit download action. Profile editing, generation, and review remain available through existing tools and APIs.
Rolling back one stored revision reuses conditional replace on the page that already shows that revision.

# Prior art

Expand All @@ -340,6 +340,6 @@ aggregation, Profile editing, and batch reports require separate designs.

# Future possibilities

Future work can add conditional Profile editing, historical comparisons, and explicitly named latest-Scope report
Future work can add conditional Profile editing and explicitly named latest-Scope report
downloads. Improvements to existing Prompt and Topic Memory pages should address demonstrated gaps separately while
retaining Scope permissions and exact references.
2 changes: 1 addition & 1 deletion docs/zh/development/dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Dashboard 是 PowerContext 中供个人使用和演示的内容查看器,默

用户进入 Dashboard 时,可能想确认某项约定,查找解决过类似问题的经验,或继续一项中断的工作。页面需要让用户确定正在查看哪个范围,找到相关记录,并在需要时核对原始材料。

1.0 的核心是阅读已有内容。记忆、经验、技能和交接可以分别存在:只有记忆的范围也应当能够正常使用;没有内容的范围仍有明确的入口和页面结构。生成、审核和保存由现有工具与接口完成,阅读这些结果不应要求用户先配置生成能力。
1.0 的核心是阅读已有内容。现有页面同时列出修订历史、比较两个修订,并通过接口已有的条件替换把某一份已保存修订写成新的当前版本。记忆只提供历史和比较,因为替换记忆是追加条目,而不是把整份快照恢复回去。记忆、经验、技能和交接可以分别存在:只有记忆的范围也应当能够正常使用;没有内容的范围仍有明确的入口和页面结构。生成、审核和保存由现有工具与接口完成,阅读这些结果不应要求用户先配置生成能力。

页面的业务主题来自范围名称、摘要和保存的内容。支付服务、客户访谈或个人研究可以使用同一套界面,不需要为每种业务另造导航。新增区块时,应先说明它帮助用户完成哪项工作,以及现有数据能否支持它表达的含义。

Expand Down
7 changes: 3 additions & 4 deletions docs/zh/rfcs/1468_scope_owned_prompt_management.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,11 +262,10 @@ GET /v1/scopes/project:payments/artifacts/prompt/memory.extract/revisions/2

1. 读取旧的 exact revision;
2. 读取 current head 与 ETag;
3. 使用旧 revision 的 `content` 和 current ETag 替换 current head;
3. 使用旧 revision 的 `content`、current ETag、`restored_from_revision` 和非空 `reason` 替换 current head;
4. 得到一个新 revision,其 content digest 与被恢复 revision 相同。

例如,revision 5 为 current 时恢复 revision 2,会创建 revision 6。Revision 2 到 5 继续可读。通用 request audit
标识 actor 与 request;与旧 content 相同可通过 content digest 确认。Server 绝不把 head pointer 向后移动。
例如,revision 5 为 current 时恢复 revision 2,会创建 revision 6。Revision 2 到 5 继续可读。新 revision 记下源修订、原因和已认证主体。此后每个新 revision 都写入 `created_at`。与旧 content 相同可通过 content digest 确认。Server 绝不把 head pointer 向后移动。两个回滚字段都不提供时仍是普通替换。给出源修订但没有有效原因、源修订就是当前 head,或正文与该源修订不一致,返回 422。

# Reference-level explanation

Expand Down Expand Up @@ -770,7 +769,7 @@ conditional replacement 中,可以保留单调历史,并使用与所有更
- **Mutable cross-Scope Prompt reference:** 允许一个 Scope 在没有本地 revision 的情况下改变另一个 Scope 的行为。
- **Prompt DSL 或 variables:** 在出现具体需求前增加 compiler 与 injection 复杂度。
- **Draft、review 与 activation workflow:** 重复 Candidate/Review 概念,且首个 administrative vertical slice 不需要。
- **专用 rollback endpoint:** exact read 加 conditional replacement 已经表达其安全语义。
- **专用 rollback endpoint:** exact read 加 conditional replacement 已经表达其安全语义。替换请求可以带上源修订和原因,不新增路由,也不新增权限。

如果不做此设计,operational prompt 仍固定在 deployment composition 阶段,客户只能 fork Runtime code 或运行多个部署
来获得不同 prompt 行为。
Expand Down
Loading