pi-daddy 0.40.0 → 0.41.0

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 (87) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/contracts/ledger-record/v1/fixtures/capability-decision.json +1 -0
  3. package/contracts/ledger-record/v1/fixtures/child-lifecycle.json +16 -0
  4. package/contracts/ledger-record/v1/fixtures/ledger-record.jsonl +3 -3
  5. package/contracts/ledger-record/v1/fixtures/workspace-lease.json +1 -0
  6. package/contracts/ledger-record/v1/governance-event.schema.json +100 -0
  7. package/dist/advisors/advisor.d.ts +19 -1
  8. package/dist/advisors/advisor.d.ts.map +1 -1
  9. package/dist/advisors/advisor.js +62 -2
  10. package/dist/advisors/advisor.js.map +1 -1
  11. package/dist/advisors/decider.d.ts +2 -4
  12. package/dist/advisors/decider.d.ts.map +1 -1
  13. package/dist/advisors/decider.js.map +1 -1
  14. package/dist/advisors/settings.d.ts +3 -1
  15. package/dist/advisors/settings.d.ts.map +1 -1
  16. package/dist/advisors/settings.js +4 -3
  17. package/dist/advisors/settings.js.map +1 -1
  18. package/dist/executors/activity-session.d.ts +7 -0
  19. package/dist/executors/activity-session.d.ts.map +1 -1
  20. package/dist/executors/activity-session.js +101 -3
  21. package/dist/executors/activity-session.js.map +1 -1
  22. package/dist/governance/ledger-events.d.ts +23 -0
  23. package/dist/governance/ledger-events.d.ts.map +1 -1
  24. package/dist/governance/ledger-events.js +7 -0
  25. package/dist/governance/ledger-events.js.map +1 -1
  26. package/dist/governance/ledger-v3-validation.d.ts.map +1 -1
  27. package/dist/governance/ledger-v3-validation.js +29 -0
  28. package/dist/governance/ledger-v3-validation.js.map +1 -1
  29. package/dist/governance/ledger.d.ts +5 -1
  30. package/dist/governance/ledger.d.ts.map +1 -1
  31. package/dist/governance/ledger.js +4 -0
  32. package/dist/governance/ledger.js.map +1 -1
  33. package/dist/kernel/delegate-types.d.ts +2 -0
  34. package/dist/kernel/delegate-types.d.ts.map +1 -1
  35. package/dist/kernel/delegate-types.js.map +1 -1
  36. package/dist/kernel/delegate.d.ts.map +1 -1
  37. package/dist/kernel/delegate.js +3 -1
  38. package/dist/kernel/delegate.js.map +1 -1
  39. package/dist/kernel/env-names.d.ts +3 -0
  40. package/dist/kernel/env-names.d.ts.map +1 -1
  41. package/dist/kernel/env-names.js +5 -0
  42. package/dist/kernel/env-names.js.map +1 -1
  43. package/dist/kernel/episode-id.d.ts +6 -0
  44. package/dist/kernel/episode-id.d.ts.map +1 -0
  45. package/dist/kernel/episode-id.js +13 -0
  46. package/dist/kernel/episode-id.js.map +1 -0
  47. package/dist/kernel/ledger-identifiers.d.ts.map +1 -1
  48. package/dist/kernel/ledger-identifiers.js +20 -1
  49. package/dist/kernel/ledger-identifiers.js.map +1 -1
  50. package/dist/kernel/propagation.d.ts +4 -2
  51. package/dist/kernel/propagation.d.ts.map +1 -1
  52. package/dist/kernel/propagation.js +6 -2
  53. package/dist/kernel/propagation.js.map +1 -1
  54. package/dist/products/activity-timeline.d.ts +3 -0
  55. package/dist/products/activity-timeline.d.ts.map +1 -1
  56. package/dist/products/activity-timeline.js +6 -0
  57. package/dist/products/activity-timeline.js.map +1 -1
  58. package/extensions/activity-timeline.ts +11 -5
  59. package/extensions/advisor-session.ts +3 -0
  60. package/extensions/chain-ledger.ts +1 -0
  61. package/extensions/delegation-ledger.ts +1 -0
  62. package/extensions/effort-advice.ts +6 -5
  63. package/extensions/execute-child.ts +16 -0
  64. package/extensions/grant-store-refusal.ts +1 -0
  65. package/extensions/grants-command.ts +4 -4
  66. package/extensions/grants.ts +4 -1
  67. package/extensions/pruning-advice.ts +37 -6
  68. package/extensions/reload-environment.ts +1 -0
  69. package/extensions/run-delegation.ts +10 -1
  70. package/extensions/session-environment.ts +9 -0
  71. package/extensions/session.ts +27 -4
  72. package/extensions/workspace-runtime.ts +5 -0
  73. package/package.json +1 -1
  74. package/src/advisors/advisor.ts +83 -3
  75. package/src/advisors/decider.ts +2 -4
  76. package/src/advisors/settings.ts +6 -4
  77. package/src/executors/activity-session.ts +105 -3
  78. package/src/governance/ledger-events.ts +35 -1
  79. package/src/governance/ledger-v3-validation.ts +44 -0
  80. package/src/governance/ledger.ts +8 -0
  81. package/src/kernel/delegate-types.ts +2 -0
  82. package/src/kernel/delegate.ts +2 -0
  83. package/src/kernel/env-names.ts +5 -0
  84. package/src/kernel/episode-id.ts +18 -0
  85. package/src/kernel/ledger-identifiers.ts +21 -1
  86. package/src/kernel/propagation.ts +8 -0
  87. package/src/products/activity-timeline.ts +8 -0
@@ -1,7 +1,27 @@
1
1
  const DISPLAY_IDENTIFIER = /^[A-Za-z0-9@*][A-Za-z0-9@*._:/-]{0,511}$/;
2
2
  const CORRELATION_IDENTIFIER = /^[A-Za-z0-9@*][A-Za-z0-9@*._:/-]{0,127}$/;
3
3
  const CAPABILITY_TAIL = /^[A-Za-z0-9@*][A-Za-z0-9@*._/-]{0,255}$/;
4
- const CAPABILITY_PREFIXES = ["tool:", "skill:", "agent:", "workspace:", "ext:"] as const;
4
+ /**
5
+ * The namespaces a ledger capability field may hold — **derived, not restated.**
6
+ *
7
+ * **This was a second copy of the list and it took a whole namespace down.** ADR-0078 added `context:` to
8
+ * `CAPABILITY_NAMESPACE_PREFIXES` and nothing added it here, so `isLedgerCapabilityIdentifier("context:summary")`
9
+ * was false. Every capability-decision event carries `requested`, `parentGrant`, `effective`, `denied`, `clipped`
10
+ * and `gatedBlocked`, all validated with this, so a session whose grant contained ANY `context:` id could not
11
+ * write a decision at all — and a ledger write that throws denies the delegation. The operator saw
12
+ * `delegation refused: grants: ledger write failed, denying — TypeError: invalid ledger v3 event: capability
13
+ * decision requested must contain capability identifiers`, with no indication that the cause was the namespace.
14
+ *
15
+ * 0.40.0 widened the blast radius rather than causing it: held-back definitions began contributing `context:`
16
+ * ids to the generated grant, so far more sessions carry one.
17
+ *
18
+ * Importing the kernel's list is the fix, and the point. This package has spent a whole session finding the same
19
+ * shape — one rule, two spellings, the guard on the quieter one — and a validator that restates what it
20
+ * validates is that shape with a ledger behind it.
21
+ */
22
+ import { CAPABILITY_NAMESPACE_PREFIXES } from "./capabilities.ts";
23
+
24
+ const CAPABILITY_PREFIXES = CAPABILITY_NAMESPACE_PREFIXES;
5
25
 
6
26
  /** Identifier text safe to copy onto the operator's terminal; prose belongs in no ledger display field. */
7
27
  export function isLedgerDisplayIdentifier(value: unknown): value is string {
@@ -33,12 +33,14 @@ import { inheritApprovals, type InheritableApproval } from "./approval.ts";
33
33
  import { assertCapabilitiesArePropagatable } from "./capabilities.ts";
34
34
  import {
35
35
  ENV_ADVISOR_MODEL,
36
+ ENV_ADVISOR_TASK_EGRESS,
36
37
  ENV_ADVISOR_KEY,
37
38
  ENV_ADVISOR,
38
39
  ENV_GRANT,
39
40
  ENV_FANOUT,
40
41
  ENV_PARENT_ID,
41
42
  ENV_EXECUTION_ID,
43
+ ENV_EPISODE_ID,
42
44
  ENV_DEPTH,
43
45
  ENV_MAX_DEPTH,
44
46
  ENV_GATED,
@@ -51,6 +53,7 @@ export {
51
53
  ENV_FANOUT,
52
54
  ENV_PARENT_ID,
53
55
  ENV_EXECUTION_ID,
56
+ ENV_EPISODE_ID,
54
57
  ENV_DEPTH,
55
58
  ENV_MAX_DEPTH,
56
59
  ENV_GATED,
@@ -88,6 +91,7 @@ export const GRANT_ENV_KEYS = [
88
91
  // child. Named here rather than claimed away: "stripped from every child" would be false on that path.
89
92
  ENV_ADVISOR_KEY,
90
93
  ENV_ADVISOR,
94
+ ENV_ADVISOR_TASK_EGRESS,
91
95
  ENV_GRANT,
92
96
  ENV_DEPTH,
93
97
  ENV_MAX_DEPTH,
@@ -97,6 +101,7 @@ export const GRANT_ENV_KEYS = [
97
101
  ENV_FANOUT,
98
102
  ENV_PARENT_ID,
99
103
  ENV_EXECUTION_ID,
104
+ ENV_EPISODE_ID,
100
105
  // ADR-0042: a child must never keep its parent's unnarrowed pin, so it is stripped like every other
101
106
  // governance value and re-supplied only by the spawn plan.
102
107
  ENV_WORKSPACE_PIN,
@@ -262,6 +267,8 @@ export interface ChildEnvInput {
262
267
  * child then inherits no pin and can route nowhere — which is the fail-closed direction.
263
268
  */
264
269
  workspacePin?: WorkspacePins;
270
+ /** Stable identity shared by this root session and every descendant. */
271
+ episodeId?: string;
265
272
  /** This session's depth; children are one deeper. */
266
273
  depth: number;
267
274
  maxDepth: number;
@@ -342,6 +349,7 @@ export function childEnv(input: ChildEnvInput): Record<string, string> {
342
349
  env[ENV_APPROVED] = inheritApprovals(input.approved ?? [], inheritable).join(",");
343
350
  // Empty is an explicit one-run ledger opt-out and must overwrite a prior publication too.
344
351
  if (input.ledgerPath !== undefined) env[ENV_LEDGER] = input.ledgerPath;
352
+ if (input.episodeId !== undefined) env[ENV_EPISODE_ID] = input.episodeId;
345
353
  // ADR-0042. ALWAYS written when this session has any pin at all, empty string included, for the same reason
346
354
  // `ENV_APPROVED` is: an omitted key does not overwrite, so a child would inherit the PARENT's unnarrowed pin
347
355
  // through the process-global publication path. An empty value parses back as "a pin was established and you
@@ -4,6 +4,8 @@ import { constants } from "node:fs";
4
4
  import { appendFile, mkdir, open, readFile, realpath, rename, writeFile } from "node:fs/promises";
5
5
  import { dirname, join, resolve, sep } from "node:path";
6
6
  import { activityTimelinePath } from "../kernel/project-paths.ts";
7
+ import { isEpisodeId, newEpisodeId } from "../kernel/episode-id.ts";
8
+ import { ENV_EPISODE_ID } from "../kernel/env-names.ts";
7
9
  import { appendRecord, readRecords } from "../governance/record.ts";
8
10
 
9
11
  export const ACTIVITY_TIMELINE_VERSION = 1 as const;
@@ -35,6 +37,8 @@ export interface ActivityEvent {
35
37
  kind: string;
36
38
  at: string;
37
39
  rootId: string;
40
+ /** Added after v1 shipped; absent on retained events written before episode identity existed. */
41
+ episodeId?: string;
38
42
  taskId: string;
39
43
  parentTaskId?: string;
40
44
  agentId?: string;
@@ -541,6 +545,7 @@ export class ActivityTimelineRecorder {
541
545
  readonly contentEnabled: boolean;
542
546
  readonly path: string;
543
547
  readonly rootId: string;
548
+ readonly episodeId: string;
544
549
  private taskId?: string;
545
550
  constructor(cwd: string, env: NodeJS.ProcessEnv = process.env) {
546
551
  const configured = env[ENV_ACTIVITY_TIMELINE]?.trim();
@@ -550,6 +555,8 @@ export class ActivityTimelineRecorder {
550
555
  const identity = activityIdentity(cwd, env);
551
556
  this.path = identity.path;
552
557
  this.rootId = identity.rootId;
558
+ const inheritedEpisodeId = env[ENV_EPISODE_ID]?.trim();
559
+ this.episodeId = isEpisodeId(inheritedEpisodeId) ? inheritedEpisodeId : newEpisodeId();
553
560
  this.taskId = identity.taskId;
554
561
  }
555
562
  get task(): string | undefined {
@@ -620,6 +627,7 @@ export class ActivityTimelineRecorder {
620
627
  kind,
621
628
  at: new Date().toISOString(),
622
629
  rootId: this.rootId,
630
+ episodeId: this.episodeId,
623
631
  taskId: this.taskId,
624
632
  ...fields,
625
633
  };