@astrosheep/keiyaku 4.5.19 → 4.5.21

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.
Files changed (197) hide show
  1. package/README.md +4 -4
  2. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +14 -7
  3. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +53 -20
  4. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/references/automation.md +237 -0
  5. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +6 -7
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +2 -4
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +3 -3
  8. package/build/src/akuma/akuma-handle.d.ts +5 -1
  9. package/build/src/akuma/akuma-handle.js +4 -1
  10. package/build/src/akuma/akuma-instance.d.ts +7 -2
  11. package/build/src/akuma/akuma-instance.js +14 -7
  12. package/build/src/akuma/akuma-observe.d.ts +11 -0
  13. package/build/src/akuma/akuma-observe.js +23 -0
  14. package/build/src/akuma/akuma-product.d.ts +2 -0
  15. package/build/src/akuma/akuma-product.js +6 -0
  16. package/build/src/akuma/akuma.d.ts +20 -1
  17. package/build/src/akuma/akuma.js +2 -0
  18. package/build/src/akuma/allowed.d.ts +20 -0
  19. package/build/src/akuma/allowed.js +11 -0
  20. package/build/src/akuma/archetype.js +3 -0
  21. package/build/src/akuma/body.d.ts +25 -5
  22. package/build/src/akuma/body.js +70 -31
  23. package/build/src/akuma/call-request.d.ts +5 -0
  24. package/build/src/akuma/call-request.js +14 -4
  25. package/build/src/akuma/fleet-execution.d.ts +28 -0
  26. package/build/src/akuma/fleet-execution.js +36 -4
  27. package/build/src/akuma/fleet-observation.d.ts +54 -0
  28. package/build/src/akuma/fleet-request.d.ts +10 -0
  29. package/build/src/akuma/fleet-request.js +13 -3
  30. package/build/src/akuma/heart/facts.d.ts +2 -0
  31. package/build/src/akuma/heart/index.d.ts +1 -0
  32. package/build/src/akuma/heart/index.js +4 -1
  33. package/build/src/akuma/heart/rows.d.ts +2 -0
  34. package/build/src/akuma/heart/rows.js +7 -5
  35. package/build/src/akuma/heart/schema.d.ts +1 -1
  36. package/build/src/akuma/heart/schema.js +3 -1
  37. package/build/src/akuma/heart/tells.js +6 -5
  38. package/build/src/akuma/heart/timeline.js +1 -1
  39. package/build/src/akuma/provider-recipe.d.ts +1 -0
  40. package/build/src/akuma/provider-recipe.js +5 -0
  41. package/build/src/akuma/provider.d.ts +1 -1
  42. package/build/src/akuma/provider.js +1 -1
  43. package/build/src/akuma/providers/acp/core.js +3 -6
  44. package/build/src/akuma/providers/acp/index.js +3 -0
  45. package/build/src/akuma/providers/claude/index.js +10 -10
  46. package/build/src/akuma/providers/codex-app-server/index.js +12 -11
  47. package/build/src/akuma/providers/execution-environment.d.ts +6 -0
  48. package/build/src/akuma/providers/execution-environment.js +24 -0
  49. package/build/src/akuma/providers/grok-build/index.js +3 -0
  50. package/build/src/akuma/providers/opencode-sdk/index.js +32 -23
  51. package/build/src/akuma/providers/opencode-sdk/session.d.ts +8 -1
  52. package/build/src/akuma/providers/opencode-sdk/session.js +6 -5
  53. package/build/src/akuma/providers/pi/events.js +7 -2
  54. package/build/src/akuma/providers/pi/index.js +5 -2
  55. package/build/src/akuma/request-observation.d.ts +45 -0
  56. package/build/src/akuma/request-observation.js +162 -0
  57. package/build/src/akuma/request-rendezvous.d.ts +6 -3
  58. package/build/src/akuma/request-rendezvous.js +80 -14
  59. package/build/src/akuma/request-serve.js +27 -4
  60. package/build/src/akuma/request-wire.d.ts +5 -0
  61. package/build/src/akuma/request-wire.js +2 -0
  62. package/build/src/akuma/turn-drive.d.ts +1 -0
  63. package/build/src/akuma/turn-drive.js +2 -0
  64. package/build/src/akuma-body.js +5 -0
  65. package/build/src/body/amend.js +6 -4
  66. package/build/src/body/decode.d.ts +3 -1
  67. package/build/src/body/decode.js +53 -17
  68. package/build/src/body/region.d.ts +9 -1
  69. package/build/src/body/region.js +87 -12
  70. package/build/src/body/render.js +1 -1
  71. package/build/src/body/verification.d.ts +3 -1
  72. package/build/src/body/verification.js +4 -1
  73. package/build/src/cli/accepted.js +19 -2
  74. package/build/src/cli/commands/akuma-invoke.d.ts +3 -1
  75. package/build/src/cli/commands/akuma-invoke.js +134 -14
  76. package/build/src/cli/commands/akuma.js +24 -12
  77. package/build/src/cli/commands/contract-help.d.ts +15 -15
  78. package/build/src/cli/commands/contract-help.js +45 -19
  79. package/build/src/cli/commands/contract-invoke.d.ts +3 -0
  80. package/build/src/cli/commands/contract-invoke.js +25 -11
  81. package/build/src/cli/commands/contract.js +6 -4
  82. package/build/src/cli/commands/install.d.ts +1 -1
  83. package/build/src/cli/commands/install.js +1 -1
  84. package/build/src/cli/commands/status-set.js +15 -24
  85. package/build/src/cli/commands/task.js +18 -18
  86. package/build/src/cli/invoke.d.ts +3 -0
  87. package/build/src/cli/invoke.js +58 -23
  88. package/build/src/cli/main.js +5 -0
  89. package/build/src/cli/parse.d.ts +3 -0
  90. package/build/src/cli/parse.js +26 -4
  91. package/build/src/cli/render/akuma-activity.d.ts +100 -2
  92. package/build/src/cli/render/akuma-activity.js +485 -40
  93. package/build/src/cli/render/akuma.d.ts +10 -0
  94. package/build/src/cli/render/akuma.js +31 -21
  95. package/build/src/cli/render/audit.js +1 -1
  96. package/build/src/cli/render/board.js +1 -1
  97. package/build/src/cli/render/catalog.js +16 -13
  98. package/build/src/cli/render/contract-history.js +39 -10
  99. package/build/src/cli/render/contract-observation.js +10 -6
  100. package/build/src/cli/render/contract.js +109 -106
  101. package/build/src/cli/render/execution-progress.d.ts +26 -0
  102. package/build/src/cli/render/execution-progress.js +178 -0
  103. package/build/src/cli/render/kanshi-akuma.js +27 -39
  104. package/build/src/cli/render/kanshi.js +33 -26
  105. package/build/src/cli/render/nuke.js +1 -1
  106. package/build/src/cli/render/receipt.d.ts +1 -1
  107. package/build/src/cli/render/receipt.js +6 -6
  108. package/build/src/cli/render/refusal.js +10 -7
  109. package/build/src/cli/render/region.js +1 -1
  110. package/build/src/cli/render/settings.js +12 -2
  111. package/build/src/cli/render/status-line.d.ts +30 -0
  112. package/build/src/cli/render/status-line.js +58 -0
  113. package/build/src/cli/render/status-set.js +1 -1
  114. package/build/src/cli/render/task.d.ts +2 -0
  115. package/build/src/cli/render/task.js +11 -7
  116. package/build/src/cli/render/terminal.d.ts +0 -1
  117. package/build/src/cli/render/terminal.js +47 -15
  118. package/build/src/cli/result.d.ts +1 -0
  119. package/build/src/cli/runtime.d.ts +2 -0
  120. package/build/src/cli/runtime.js +36 -4
  121. package/build/src/cli/usage.js +2 -2
  122. package/build/src/cli/version.d.ts +1 -0
  123. package/build/src/cli/version.js +25 -0
  124. package/build/src/git/hooks.d.ts +13 -1
  125. package/build/src/git/hooks.js +2 -1
  126. package/build/src/git/workspace.d.ts +1 -1
  127. package/build/src/git/workspace.js +1 -1
  128. package/build/src/identity/mint.d.ts +13 -0
  129. package/build/src/identity/mint.js +26 -0
  130. package/build/src/identity/normalize.d.ts +4 -0
  131. package/build/src/identity/normalize.js +30 -0
  132. package/build/src/index.d.ts +2 -0
  133. package/build/src/index.js +1 -0
  134. package/build/src/kanshi/read.js +17 -4
  135. package/build/src/kanshi/report.d.ts +1 -0
  136. package/build/src/library/akuma-creation.d.ts +2 -0
  137. package/build/src/library/akuma-creation.js +34 -18
  138. package/build/src/library/audit.d.ts +2 -0
  139. package/build/src/library/audit.js +1 -0
  140. package/build/src/library/bind.js +18 -16
  141. package/build/src/library/composition.d.ts +1 -0
  142. package/build/src/library/contract-bind.d.ts +3 -1
  143. package/build/src/library/contract-bind.js +5 -3
  144. package/build/src/library/contract-execution.d.ts +2 -0
  145. package/build/src/library/contract-execution.js +15 -1
  146. package/build/src/library/contract-forwarding.d.ts +4 -0
  147. package/build/src/library/contract-forwarding.js +3 -0
  148. package/build/src/library/contract-handle.d.ts +7 -0
  149. package/build/src/library/contract-handle.js +25 -0
  150. package/build/src/library/contract-operations.d.ts +7 -2
  151. package/build/src/library/contract-operations.js +21 -1
  152. package/build/src/library/contract-types.d.ts +1 -0
  153. package/build/src/library/execution-result.d.ts +2 -2
  154. package/build/src/library/execution.d.ts +8 -0
  155. package/build/src/library/execution.js +102 -0
  156. package/build/src/library/fleet.d.ts +4 -1
  157. package/build/src/library/fleet.js +32 -8
  158. package/build/src/library/keiyaku.d.ts +2 -0
  159. package/build/src/library/mutation.js +15 -7
  160. package/build/src/plugin/akuma-signals.d.ts +6 -0
  161. package/build/src/plugin/akuma-signals.js +9 -1
  162. package/build/src/plugin/public.d.ts +6 -2
  163. package/build/src/plugin/runtime.d.ts +1 -3
  164. package/build/src/plugin/runtime.js +95 -103
  165. package/build/src/protocol/amend.js +4 -3
  166. package/build/src/protocol/attempt.d.ts +2 -0
  167. package/build/src/protocol/bind.js +41 -14
  168. package/build/src/protocol/completion.d.ts +3 -0
  169. package/build/src/protocol/completion.js +35 -11
  170. package/build/src/protocol/deliver.js +165 -92
  171. package/build/src/protocol/execution-observation.d.ts +181 -0
  172. package/build/src/protocol/execution-observation.js +45 -0
  173. package/build/src/protocol/intent.d.ts +18 -22
  174. package/build/src/protocol/intent.js +63 -41
  175. package/build/src/protocol/operations.d.ts +2 -0
  176. package/build/src/protocol/placement.js +5 -1
  177. package/build/src/protocol/progress.d.ts +5 -1
  178. package/build/src/protocol/progress.js +10 -1
  179. package/build/src/protocol/read/status.d.ts +1 -0
  180. package/build/src/protocol/read/status.js +10 -2
  181. package/build/src/protocol/reintegrate.d.ts +1 -1
  182. package/build/src/protocol/reintegrate.js +70 -43
  183. package/build/src/protocol/result-codec.js +27 -11
  184. package/build/src/protocol/review.js +53 -30
  185. package/build/src/protocol/run.d.ts +83 -36
  186. package/build/src/protocol/run.js +90 -75
  187. package/build/src/runtime/proc/run.d.ts +16 -4
  188. package/build/src/runtime/proc/run.js +64 -22
  189. package/build/src/runtime/proc/windows-launch.exe +0 -0
  190. package/build/src/settings.js +5 -14
  191. package/build/src/task/document.d.ts +5 -1
  192. package/build/src/task/document.js +6 -1
  193. package/build/src/verification/execution.d.ts +10 -2
  194. package/build/src/verification/execution.js +143 -42
  195. package/build/src/verification/observation.d.ts +41 -0
  196. package/build/src/verification/observation.js +29 -0
  197. package/package.json +3 -1
@@ -1,7 +1,17 @@
1
1
  import type { AkumaInvocationResult } from "../commands/akuma-invoke.js";
2
2
  import type { ParsedCommand } from "../parse.js";
3
+ import { type ObservedCallHead } from "./akuma-activity.js";
3
4
  import { type TextRenderContext } from "./terminal.js";
4
5
  export { akumaRawAnswer } from "./akuma-activity.js";
6
+ /**
7
+ * The head a streamed observing call opens with: the identity its birth already
8
+ * established, its Contract association, and the birth's diagnostics. The
9
+ * detached receipt's cwd row deliberately stays out; the observation stream
10
+ * owns this call's presentation.
11
+ */
12
+ export declare function callObservationHead(result: Extract<AkumaInvocationResult, {
13
+ action: "call";
14
+ }>["result"]): ObservedCallHead;
5
15
  export declare function renderAkumaText(command: ParsedCommand, result: AkumaInvocationResult, context?: TextRenderContext): string;
6
16
  export declare function akumaExitCode(result: AkumaInvocationResult): number;
7
17
  export declare function akumaJsonValue(result: AkumaInvocationResult): unknown;
@@ -1,6 +1,6 @@
1
1
  import { parseAkumaStatus } from "../../akuma/akuma.js";
2
2
  import { DEFAULT_CONTEXT, akumaRawAnswer, associatedIdentity, historyText, killResultText, mutationObservationStageText, snapshotHeading, snapshotText, tellText, waitText, } from "./akuma-activity.js";
3
- import { safeText, tone } from "./terminal.js";
3
+ import { safeText } from "./terminal.js";
4
4
  export { akumaRawAnswer } from "./akuma-activity.js";
5
5
  function dispatchLines(stage) {
6
6
  if (stage.kind === "none")
@@ -12,8 +12,28 @@ function dispatchLines(stage) {
12
12
  return [`dispatch failed conflict ${stage.failure.current.contractId}`];
13
13
  return [`dispatch failed ${stage.failure.kind} ${safeText(stage.failure.diagnostic)}`];
14
14
  }
15
- function executionCwdLine(result) {
16
- return [`cwd ${safeText(result.execution.cwd)}`];
15
+ /**
16
+ * The head a streamed observing call opens with: the identity its birth already
17
+ * established, its Contract association, and the birth's diagnostics. The
18
+ * detached receipt's cwd row deliberately stays out; the observation stream
19
+ * owns this call's presentation.
20
+ */
21
+ export function callObservationHead(result) {
22
+ const alias = result.alias.kind === "aliased" ? result.alias.alias.alias : undefined;
23
+ const contractId = result.dispatch.kind === "dispatched" ? result.dispatch.dispatch.contractId : undefined;
24
+ const facts = [
25
+ ...dispatchLines(result.dispatch),
26
+ ...(result.readonly?.enforcement === "none" ? [`! ${safeText(result.readonly.diagnostic)}`] : []),
27
+ ...(result.alias.kind === "failed"
28
+ ? [`alias failed ${result.alias.failure.kind} ${safeText(result.alias.failure.diagnostic)}`]
29
+ : []),
30
+ ];
31
+ return {
32
+ id: result.akuma,
33
+ ...(alias === undefined ? {} : { alias }),
34
+ contract: contractId === undefined ? { kind: "none" } : { kind: "associated", contractId },
35
+ facts,
36
+ };
17
37
  }
18
38
  function callText(result, context) {
19
39
  if (result.schemaAnswer !== undefined)
@@ -24,27 +44,19 @@ function callText(result, context) {
24
44
  const restraint = result.result.readonly?.enforcement === "none" ? [`! ${safeText(result.result.readonly.diagnostic)}`] : [];
25
45
  if (result.result.alias.kind === "failed")
26
46
  facts.push(`alias failed ${result.result.alias.failure.kind} ${safeText(result.result.alias.failure.diagnostic)}`);
27
- const cwd = executionCwdLine(result.result);
28
47
  if (result.result.observation.kind === "detached") {
29
48
  const lines = [
30
49
  associatedIdentity(result.result.akuma, alias),
31
- ...(contractId === undefined ? [] : [` \u{1f4dc} ${safeText(contractId)}`]),
32
- ` \u{1f4c1} ${safeText(result.result.execution.cwd)}`,
50
+ ...(contractId === undefined ? [] : [` -> ${safeText(contractId)}`]),
51
+ ` cwd ${safeText(result.result.execution.cwd)}`,
33
52
  ...restraint,
34
53
  ...facts,
35
54
  ];
36
- if (!(result.result.dispatch.kind === "failed" ||
37
- result.result.alias.kind === "failed" ||
38
- result.result.readonly?.enforcement === "none")) {
39
- const selector = result.result.alias.kind === "aliased" ? result.result.alias.alias.alias : result.result.akuma;
40
- lines.push(tone("-----", "dim", context.color), `$ keiyaku wait ${selector} --timeout 5m`, tone("to wait", "dim", context.color));
41
- }
42
55
  return lines.join("\n");
43
56
  }
44
57
  if (result.result.observation.kind === "failed") {
45
58
  return [
46
59
  ...snapshotHeading(result.result.akuma, alias, contractId === undefined ? { kind: "none" } : { kind: "associated", contractId }),
47
- ...cwd,
48
60
  ...restraint,
49
61
  ...facts,
50
62
  `! error ${safeText(result.result.observation.failure.diagnostic)}`,
@@ -53,23 +65,21 @@ function callText(result, context) {
53
65
  return snapshotText({
54
66
  status: parseAkumaStatus(result.result.observation.status),
55
67
  contract: contractId === undefined ? { kind: "none" } : { kind: "associated", contractId },
56
- }, context, { ...(alias === undefined ? {} : { alias }), facts: [...cwd, ...facts] });
68
+ }, context, { ...(alias === undefined ? {} : { alias }), facts: [...facts] });
57
69
  }
58
70
  export function renderAkumaText(command, result, context = DEFAULT_CONTEXT) {
59
71
  const answer = akumaRawAnswer(result);
60
- if (answer !== undefined) {
61
- if (result.action !== "call")
62
- return answer;
63
- const cwd = executionCwdLine(result.result);
64
- return `${cwd.join("\n")}\n\n${answer}`;
65
- }
72
+ if (answer !== undefined)
73
+ return answer;
66
74
  if (result.action === "tell" && result.mode === "schema")
67
75
  return JSON.stringify(result.result);
68
76
  switch (result.action) {
69
77
  case "call":
70
78
  return callText(result, context);
71
79
  case "status":
72
- return snapshotText(result.status, context, { ...(result.alias === undefined ? {} : { alias: result.alias }) });
80
+ return snapshotText(result.status, context, {
81
+ ...(result.alias === undefined ? {} : { alias: result.alias }),
82
+ });
73
83
  case "wait":
74
84
  return waitText(result, context);
75
85
  case "tell":
@@ -94,7 +94,7 @@ function recordLines(result, columns) {
94
94
  for (const fact of result.facts) {
95
95
  receiptRow(rows, " ", "journal", [{ text: fact.entry, opaque: true }, { text: `· ${fact.kind}` }], columns);
96
96
  }
97
- return [" record", ...rows.map((line) => ` ${line}`)];
97
+ return rows;
98
98
  }
99
99
  export function renderAcceptedAudit(result, context) {
100
100
  const report = result.report;
@@ -12,7 +12,7 @@ export function worldObservationFailureText(result) {
12
12
  typeof report.diagnostic !== "string") {
13
13
  return undefined;
14
14
  }
15
- return `✕ observation ${result.command}\n diagnostic ${report.diagnostic}`;
15
+ return observation ${result.command}\n diagnostic ${report.diagnostic}`;
16
16
  }
17
17
  export function renderObservation(result) {
18
18
  const failed = worldObservationFailureText(result);
@@ -1,13 +1,13 @@
1
- import { abbreviateGitIds, afterWording, candidateFact, dependentWording, displayGitId, gateFact, gitIdsInRow, verificationFact, targetFacts, } from "./contract-observation.js";
1
+ import { abbreviateGitIds, afterWording, candidateFact, dependentWording, gateFact, gitIdsInRow, verificationFact, targetFacts, } from "./contract-observation.js";
2
2
  import { safeText } from "./terminal.js";
3
- import { taskMark } from "./task.js";
3
+ import { dispositionText, taskMark } from "./task.js";
4
4
  function akumaMark(life) {
5
5
  if (life === "running")
6
6
  return "●";
7
7
  if (life === "asleep" || life === "unborn")
8
8
  return "○";
9
9
  if (life === "killed")
10
- return "";
10
+ return "×";
11
11
  if (life === "stillborn")
12
12
  return "!";
13
13
  return "?";
@@ -38,7 +38,12 @@ function renderAkumaCatalog(catalog) {
38
38
  for (const row of rows) {
39
39
  const lifeAt = "lifeAt" in row ? row.lifeAt : null;
40
40
  const activityAt = "lastActivityAt" in row ? row.lastActivityAt : null;
41
- const ages = [relativeAge(lifeAt, catalog.observedAt), relativeAge(activityAt, catalog.observedAt)].filter((age) => age !== null);
41
+ const lifeAge = relativeAge(lifeAt, catalog.observedAt);
42
+ const activityAge = relativeAge(activityAt, catalog.observedAt);
43
+ const ages = [
44
+ ...(lifeAge === null ? [] : [lifeAge]),
45
+ ...(activityAge === null || activityAge === lifeAge ? [] : [`activity ${activityAge}`]),
46
+ ];
42
47
  lines.push(`${akumaMark(row.life)} ${safeText(row.id)} · ${row.life}${ages.length === 0 ? "" : ` · ${ages.join(" · ")}`}`);
43
48
  }
44
49
  if (catalog.hasMore)
@@ -49,15 +54,15 @@ function catalogMark(row) {
49
54
  if (row.phase === "claimed")
50
55
  return "✓";
51
56
  if (row.phase === "abandoned")
52
- return "";
57
+ return "×";
53
58
  if (row.title === null)
54
59
  return "?";
55
60
  if (row.gates.reports.some((gate) => gate.current.kind === "attested" && gate.current.verdict === "unsatisfied"))
56
61
  return "!";
57
62
  if (row.targetLag.kind === "unknown")
58
63
  return "?";
59
- if (row.phase === "waiting")
60
- return "";
64
+ if (row.phase === "waiting" || row.phase === "tendered")
65
+ return "";
61
66
  return "●";
62
67
  }
63
68
  function formatAge(source, observedAt) {
@@ -78,15 +83,13 @@ function renderContractCatalog(catalog) {
78
83
  ...catalog.rows.flatMap(gitIdsInRow),
79
84
  ]);
80
85
  const rows = catalog.rows;
81
- const header = catalog.state === null
82
- ? `observedAt ${catalog.observedAt}`
83
- : `contract state ${displayGitId(catalog.state, abbreviations)} · observedAt ${catalog.observedAt}`;
86
+ const header = `observed ${catalog.observedAt}`;
84
87
  const blocks = rows.map((row) => {
85
88
  const lines = [
86
89
  `${catalogMark(row)} ${safeText(row.id)} · ${row.phase} · ${formatAge(row.phaseAt, catalog.observedAt)} · ${safeText(row.title ?? "title unavailable")}`,
87
90
  ` ${candidateFact(row.delivery)}`,
88
91
  ...targetFacts(row, abbreviations).map((fact) => ` ${safeText(fact)}`),
89
- ...(row.worktreePath === null ? [] : [` worktree ${safeText(row.worktreePath)}`]),
92
+ ...[],
90
93
  ...(verificationFact(row.verification) === undefined ? [] : [` ${verificationFact(row.verification)}`]),
91
94
  ...row.after.map((edge) => ` ${afterWording(edge)}`),
92
95
  ...(row.dependents.length === 0 ? [] : [` dependents ${row.dependents.map(dependentWording).join(" · ")}`]),
@@ -99,7 +102,7 @@ function renderContractCatalog(catalog) {
99
102
  export function renderCatalogText(catalog) {
100
103
  if (catalog.kind === "tasks") {
101
104
  return [
102
- ...catalog.rows.map((row) => `${taskMark(row.disposition)} ${safeText(row.id)} · ${row.disposition} · P${row.priority} — ${safeText(row.title)}`),
105
+ ...catalog.rows.map((row) => `${taskMark(row.disposition)} ${safeText(row.id)} · ${dispositionText(row.disposition)} · P${row.priority} — ${safeText(row.title)}`),
103
106
  ...(catalog.hasMore ? ["…"] : []),
104
107
  ].join("\n");
105
108
  }
@@ -107,7 +110,7 @@ export function renderCatalogText(catalog) {
107
110
  return renderContractCatalog(catalog);
108
111
  if (catalog.kind === "archetypes") {
109
112
  return [
110
- `available Akuma ${catalog.rows.length}`,
113
+ `available Akuma`,
111
114
  "",
112
115
  ...catalog.rows.flatMap((row) => [
113
116
  `${safeText(row.name)}${row.model === undefined ? "" : ` ${safeText(row.model)}`}`,
@@ -8,14 +8,37 @@ function journalHead(fact) {
8
8
  : `${fact.at} ${fact.kind} · ${fact.entry} · ${fact.actor}`;
9
9
  }
10
10
  function listFact(label, values) {
11
- return values.length === 0 ? [` ${label} 0`] : [` ${label} ${values.join(" · ")}`];
11
+ return values.length === 0 ? [] : [` ${label} ${values.join(" · ")}`];
12
+ }
13
+ function shortId(value) {
14
+ return /^[0-9a-f]{40}$/iu.test(value) ? value.slice(0, 7) : value;
15
+ }
16
+ /**
17
+ * A persisted subject is a canonical `[kind, value]` key set. Only its snapshot names the commit the verdict
18
+ * covers, so history speaks that component and leaves the segment and document keys to JSON.
19
+ */
20
+ function subjectSnapshot(subject) {
21
+ let parsed;
22
+ try {
23
+ parsed = JSON.parse(subject);
24
+ }
25
+ catch {
26
+ return undefined;
27
+ }
28
+ if (!Array.isArray(parsed))
29
+ return undefined;
30
+ for (const key of parsed) {
31
+ if (Array.isArray(key) && key[0] === "snapshot" && typeof key[1] === "string")
32
+ return key[1];
33
+ }
34
+ return undefined;
12
35
  }
13
36
  function journalBody(fact) {
14
37
  switch (fact.kind) {
15
38
  case "bind": {
16
39
  const { coordinates, terms } = fact.data;
17
40
  return [
18
- ` start commit ${coordinates.start}`,
41
+ ` start commit ${shortId(coordinates.start)}`,
19
42
  ...(coordinates.target === undefined ? [] : [` target ${coordinates.target}`]),
20
43
  ` workspace ${coordinates.workspace}`,
21
44
  ...listFact("gates", terms.gates),
@@ -29,24 +52,30 @@ function journalBody(fact) {
29
52
  case "deliver": {
30
53
  const { tenderSnapshot, integration, method, policy } = fact.data;
31
54
  return [
32
- ` tender commit ${tenderSnapshot}`,
33
- ` predecessor commit ${integration.predecessor}`,
34
- ` integration commit ${integration.snapshot}`,
55
+ ` tender commit ${shortId(tenderSnapshot)}`,
56
+ ` predecessor commit ${shortId(integration.predecessor)}`,
57
+ ` integration commit ${shortId(integration.snapshot)}`,
35
58
  ` content identity (not commit) ${integration.changeId}`,
36
59
  ` method ${method}`,
37
- ` require-branches-to-be-up-to-date ${String(policy.requireBranchesToBeUpToDate)}`,
60
+ ` require branches up to date ${String(policy.requireBranchesToBeUpToDate)}`,
38
61
  ];
39
62
  }
40
63
  case "reintegrated":
41
- return [` predecessor commit ${fact.data.predecessor}`, ` integration commit ${fact.data.snapshot}`];
64
+ return [
65
+ ` predecessor commit ${shortId(fact.data.predecessor)}`,
66
+ ` integration commit ${shortId(fact.data.snapshot)}`,
67
+ ];
42
68
  case "attestation": {
69
+ const snapshot = subjectSnapshot(fact.data.subject);
43
70
  const lines = [
44
71
  ` gate ${fact.data.gate}`,
45
72
  ` verdict ${fact.data.verdict}`,
46
- ` subject identity ${fact.data.subject}`,
73
+ snapshot === undefined ? " subject verification" : ` subject verification · snapshot ${shortId(snapshot)}`,
47
74
  ];
48
- if (fact.data.summary !== undefined)
49
- receiptPayload(lines, "summary", fact.data.summary);
75
+ if (fact.data.summary !== undefined) {
76
+ const clipped = fact.data.summary.length > 4096 ? `${fact.data.summary.slice(0, 4096)}\n[truncated]` : fact.data.summary;
77
+ receiptPayload(lines, "summary", clipped);
78
+ }
50
79
  return lines;
51
80
  }
52
81
  case "claimed":
@@ -1,13 +1,16 @@
1
1
  const GIT_OBJECT_ID = /^[0-9a-f]{40}$/iu;
2
+ function shortGitId(value) {
3
+ return GIT_OBJECT_ID.test(value) ? value.slice(0, 7) : value;
4
+ }
2
5
  export function gateGlyph(report) {
3
6
  if (report.current.kind === "stale")
4
- return "[~]";
7
+ return "!";
5
8
  if (report.current.kind === "missing")
6
- return "[ ]";
7
- return report.current.verdict === "satisfied" ? "[]" : "[✗]";
9
+ return "";
10
+ return report.current.verdict === "satisfied" ? "✓" : "×";
8
11
  }
9
12
  export function gateFact(report) {
10
- return `${gateGlyph(report)} ${report.gate}${report.current.kind === "stale" ? " (stale)" : ""}`;
13
+ return `${gateGlyph(report)} ${report.gate}${report.current.kind === "stale" ? " · stale" : ""}`;
11
14
  }
12
15
  export function candidateFact(delivery) {
13
16
  return `candidate ${delivery === null ? "none" : "present"}`;
@@ -16,7 +19,7 @@ export function verificationFact(status) {
16
19
  if (status === undefined)
17
20
  return undefined;
18
21
  if (status.kind === "recorded")
19
- return `verification ${status.verdict}`;
22
+ return `verification ${status.verdict}${status.snapshot === undefined ? "" : ` · on ${shortGitId(status.snapshot)}`}`;
20
23
  return `verification ${status.kind}`;
21
24
  }
22
25
  export function afterWording(edge) {
@@ -61,7 +64,8 @@ export function gitIdsInRow(row) {
61
64
  return ids;
62
65
  }
63
66
  export function displayGitId(value, abbreviations) {
64
- return abbreviations.get(value) ?? value;
67
+ const rendered = abbreviations.get(value) ?? value;
68
+ return GIT_OBJECT_ID.test(rendered) ? rendered.slice(0, 7) : rendered;
65
69
  }
66
70
  export function targetFacts(row, abbreviations) {
67
71
  if (row.target === null)