@danypops/papyrus 0.32.0 → 0.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/extension/src/index.ts +4 -3
- package/package.json +1 -1
- package/src/service.ts +23 -1
package/extension/src/index.ts
CHANGED
|
@@ -344,11 +344,12 @@ export default async function (pi: ExtensionAPI) {
|
|
|
344
344
|
name: "papyrus_graph",
|
|
345
345
|
label: "Papyrus Graph",
|
|
346
346
|
description:
|
|
347
|
-
"Link artifacts with typed edges (any kind → any kind), view subgraph,
|
|
347
|
+
"Link artifacts with typed edges (any kind → any kind), view subgraph, or read the mutation event log. " +
|
|
348
348
|
"RELATIONS: references, implements, follows, depends_on, documents, blocks, supersedes, relates_to, gates, triggers, contains, part_of. " +
|
|
349
349
|
"ACTIONS: link (from+relation+to), unlink (from+relation+to — idempotent, no error if already absent; for Task depends_on/contains prefer the tasks tool's undepend/uncontain), " +
|
|
350
|
-
"tree (id → bounded BFS subgraph),
|
|
351
|
-
"history (who did what, when — requires id, actor, or session_id)."
|
|
350
|
+
"tree (id → bounded BFS subgraph), " +
|
|
351
|
+
"history (who did what, when — requires id, actor, or session_id). " +
|
|
352
|
+
"status (id+status) exists at the protocol level but is refused for every kind with its own lifecycle (Doc/Rule/Skill/Playbook/Task/Note all reject it) -- use that kind's own domain tool for status changes (docs.activate, rules.enable, tasks.start, etc), never this.",
|
|
352
353
|
parameters: Type.Object({
|
|
353
354
|
action: Type.String({ description: "link | unlink | tree | status | history" }),
|
|
354
355
|
from: Type.Optional(Type.String()),
|
package/package.json
CHANGED
package/src/service.ts
CHANGED
|
@@ -164,9 +164,31 @@ const tasksAuthorityClaim: AuthorityClaim = {
|
|
|
164
164
|
denyMessage: () => "task lifecycle changes require a tasks.* operation so history and review invariants are preserved",
|
|
165
165
|
};
|
|
166
166
|
|
|
167
|
+
/**
|
|
168
|
+
* The same status-bypass protection Tasks and Notes already have, extended to every other kind
|
|
169
|
+
* with its own validated transition set (Doc's draft/active/archived, Rule/Skill/Playbook's
|
|
170
|
+
* active/deprecated) -- graph.status previously let a caller jump straight to any status string,
|
|
171
|
+
* skipping e.g. Doc's draft-must-go-through-active-before-archived rule entirely.
|
|
172
|
+
*/
|
|
173
|
+
function lifecycleAuthorityClaim(owner: "docs" | "rules" | "skills" | "playbooks", kind: string): AuthorityClaim {
|
|
174
|
+
return {
|
|
175
|
+
owner,
|
|
176
|
+
matchesArtifact: (candidateKind, subtype) => candidateKind === kind && !(kind === "doc" && subtype === NOTE_SUBTYPE),
|
|
177
|
+
appliesToAction: (action) => action === "status",
|
|
178
|
+
denyMessage: () => `${kind} lifecycle changes require a ${owner}.* operation so transition validation is preserved`,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
167
182
|
function createAuthorityRegistry(): AuthorityRegistry {
|
|
168
183
|
const authority = new AuthorityRegistry();
|
|
169
|
-
authority.claimAll([
|
|
184
|
+
authority.claimAll([
|
|
185
|
+
notesAuthorityClaim,
|
|
186
|
+
tasksAuthorityClaim,
|
|
187
|
+
lifecycleAuthorityClaim("docs", "doc"),
|
|
188
|
+
lifecycleAuthorityClaim("rules", "rule"),
|
|
189
|
+
lifecycleAuthorityClaim("skills", "skill"),
|
|
190
|
+
lifecycleAuthorityClaim("playbooks", "playbook"),
|
|
191
|
+
]);
|
|
170
192
|
return authority;
|
|
171
193
|
}
|
|
172
194
|
|