pm-brief 2026.10.23 → 2026.10.25

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/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## 2026.10.25 - 2026-10-25
4
+
5
+ ### Added
6
+
7
+ - Render stakeholder briefs through explicit disclosure profiles ([pm-brief-nsks](https://github.com/unbraind/pm-brief/blob/main/.agents/pm/features/pm-brief-nsks.toon))
8
+
9
+ ### Fixed
10
+
11
+ - Honor SDK blockers, lifecycle roles and UTF-8 brief budgets ([pm-brief-agze](https://github.com/unbraind/pm-brief/blob/main/.agents/pm/tasks/pm-brief-agze.toon))
12
+
13
+ ### Other
14
+
15
+ - Reconcile stale in-progress tracker records (2026-10-23) ([pm-brief-reconcile-1023](https://github.com/unbraind/pm-brief/blob/main/.agents/pm/chores/pm-brief-reconcile-1023.toon))
16
+
17
+ ## 2026.10.24 - 2026-10-24
18
+
19
+ ### Added
20
+
21
+ - Record acknowledged handoff contracts against item revisions ([pm-brief-cjxn](https://github.com/unbraind/pm-brief/blob/main/.agents/pm/features/pm-brief-cjxn.toon))
22
+ - Compare recorded decision alternatives with cited evidence ([pm-brief-ktjl](https://github.com/unbraind/pm-brief/blob/main/.agents/pm/features/pm-brief-ktjl.toon))
23
+
24
+ ### Fixed
25
+
26
+ - Daily Release workflow is failing ([pm-brief-github-7e06b2eb1b44-170](https://github.com/unbraind/pm-brief/blob/main/.agents/pm/issues/pm-brief-github-7e06b2eb1b44-170.toon))
27
+
28
+ ### Other
29
+
30
+ - Verify evidence for tracker reconciliation review ([pm-brief-review165](https://github.com/unbraind/pm-brief/blob/main/.agents/pm/chores/pm-brief-review165.toon))
31
+
3
32
  ## 2026.10.23 - 2026-10-23
4
33
 
5
34
  ### Changed
@@ -17,13 +46,6 @@
17
46
 
18
47
  - Enable GitHub CodeQL code scanning ([pm-brief-1p5o](https://github.com/unbraind/pm-brief/blob/main/.agents/pm/chores/pm-brief-1p5o.toon))
19
48
 
20
- ## 2026.10.21 - 2026-10-21
21
-
22
- ### Fixed
23
-
24
- - Enforce the requested brief budget after the final compaction step ([pm-brief-github-7e06b2eb1b44-135](https://github.com/unbraind/pm-brief/blob/main/.agents/pm/issues/pm-brief-github-7e06b2eb1b44-135.toon))
25
- - Daily Release workflow is failing ([pm-brief-github-7e06b2eb1b44-84](https://github.com/unbraind/pm-brief/blob/main/.agents/pm/issues/pm-brief-github-7e06b2eb1b44-84.toon))
26
-
27
49
  ## 2026.10.14 - 2026-10-14
28
50
 
29
51
  ### Added
@@ -42,6 +64,10 @@
42
64
 
43
65
  - Enforce the chosen rendered brief token ceiling ([pm-brief-k8no](https://github.com/unbraind/pm-brief/blob/main/.agents/pm/features/pm-brief-k8no.toon))
44
66
 
67
+ ### Fixed
68
+
69
+ - Enforce the requested brief budget after the final compaction step ([pm-brief-github-7e06b2eb1b44-135](https://github.com/unbraind/pm-brief/blob/main/.agents/pm/issues/pm-brief-github-7e06b2eb1b44-135.toon))
70
+
45
71
  ## 2026.10.5 - 2026-10-05
46
72
 
47
73
  ### Other
@@ -92,6 +118,7 @@
92
118
 
93
119
  ### Fixed
94
120
 
121
+ - Daily Release workflow is failing ([pm-brief-github-7e06b2eb1b44-84](https://github.com/unbraind/pm-brief/blob/main/.agents/pm/issues/pm-brief-github-7e06b2eb1b44-84.toon))
95
122
  - Adopt pm CLI 2026.8.30 and stop pinning which way the SDK handles an incomplete merge receipt ([pm-brief-00tc](https://github.com/unbraind/pm-brief/blob/main/.agents/pm/issues/pm-brief-00tc.toon))
96
123
 
97
124
  ### Other
package/README.md CHANGED
@@ -51,7 +51,7 @@ pm brief since 2026-07-20T00:00:00Z --until 2026-07-22 --author alice
51
51
 
52
52
  ### Ranking and Budget Flags
53
53
 
54
- - `--max-tokens` is an alias for `--token-budget`: a ceiling on the chosen rendered brief, estimated as `ceil(characters / 4)` (not a model tokenizer).
54
+ - `--max-tokens` is an alias for `--token-budget`: a ceiling on the chosen rendered brief, estimated by the SDK as `ceil(UTF-8 bytes / 4)` (not a model tokenizer).
55
55
  - `--dependency-order` prefers prerequisite items before dependent work in next-work ranking.
56
56
  - `--focus` highlights specific item ids, or `type:Type` to highlight every item of a type (repeatable or comma-separated).
57
57
  - `--include-history` adds a Recent Activity section sourced from `pm activity` to briefs and prompts; `--history-limit` controls the entry count (default 10).
@@ -88,10 +88,24 @@ const output = renderBrief(brief, "markdown");
88
88
  `renderMarkdownBrief`, `renderSlackBrief` and `renderAgentPrompt` enforce the
89
89
  selected rendering again if callers change format or modify the returned object.
90
90
  `budget.estimatedTokens` measures the rendering chosen at build time, including
91
- its own digit count. An unchanged ordinary tracker that already fits keeps its
91
+ its own digit count and trailing newline, using the SDK UTF-8 byte estimator. An unchanged ordinary tracker that already fits keeps its
92
92
  sections and fields; only the estimate disclosure can differ from older versions.
93
93
  See [budget evidence and recovery](docs/brief-budget.md) for the regression matrix.
94
94
 
95
+ Next-work recommendations exclude items with unresolved prerequisites, including
96
+ reverse `blocks` edges and missing targets. Held work remains visible in explicit
97
+ focus, blocker and risk evidence. External targets (`source_kind=global`, its
98
+ `external` alias, or external reference syntax) stay separate from local IDs:
99
+ external reverse edges cannot block local namesakes, and external references
100
+ cannot add local dependent context or ranking credit. Workspace terminal roles govern lifecycle
101
+ filters; library callers can supply `BriefOptions.statusRegistry` from
102
+ `resolveRuntimeStatusRegistry((await readSettings(pmRoot)).schema)`. Omitted
103
+ registries use SDK core defaults plus the legacy terminal `done` spelling, so
104
+ custom terminal names need their registry. An explicitly configured `done` role
105
+ takes precedence over that compatibility fallback. Native disclosure reads the
106
+ workspace registry too. See [relationship readiness](docs/relationship-readiness.md)
107
+ for the graph-shape matrix.
108
+
95
109
  ## Agent Brief Contents
96
110
 
97
111
  - workspace and item counts
@@ -471,7 +485,7 @@ immutable protocol artifacts. Receipts are append-only native comments protected
471
485
  by the host's comment lock and author/text idempotency. Native lock contention
472
486
  is retried up to three times for reads and idempotent appends; creates are never
473
487
  automatically retried. Persistent contention refuses with a retry remedy. Do not edit contract bodies
474
- or receipt comments. Create a fresh packet after a revision changes. A receipt
488
+ or receipt comments. Use repair/renew after source revisions change; create a fresh packet when the contract obligations change. A receipt
475
489
  racing a source edit is reassessed on return and every subsequent read. All source
476
490
  metadata, bodies and linked evidence contribute to content revisions, so even an
477
491
  unrelated source comment conservatively invalidates old understanding. Reads are
@@ -491,10 +505,92 @@ context delivery/usage receipts and the [since-delta candidate](https://github.c
491
505
  (`feat/since-delta-pack`)
492
506
  (`pm context-pack since --from <timestamp>` or `--cursor <cursor>`). That candidate
493
507
  owns cursor progress, changed-context selection and omission receipts. Use its delta to
494
- refresh changed context, then create a new handoff here. No history delta engine
508
+ refresh changed context, then repair existing receiver understanding here. No history delta engine
495
509
  is duplicated. pm-memory continues to own standing knowledge; `brief prompt`
496
510
  continues to generate prose. See the [contract example](docs/examples/handoff.json).
497
511
 
512
+ ## Handoff repair deltas
513
+
514
+ `brief handoff repair <packet-id> --receiver <agent>` returns only groups whose
515
+ sources changed since that receiver's last acknowledgment. `--receiver` defaults
516
+ to the active author. Each focus item is one obligation group, scoped to its
517
+ transitive declared blockers. Evidence requirements belong to each focus closure
518
+ that contains their item; evidence outside every focus closure gets its own group.
519
+ The existing contract has no per-question scope, so questions and assumptions
520
+ conservatively apply to every focus group. A shared blocker can affect several
521
+ groups. A 50-row packet with 25 independent focus/dependency pairs returns one
522
+ group when one dependency changes, preserving the other 24 acknowledgments.
523
+
524
+ ```sh
525
+ PM_AUTHOR=receiver-a pm brief handoff repair <packet-id> --json
526
+ PM_AUTHOR=receiver-a pm brief handoff renew <packet-id> --input renewal.json --json
527
+ ```
528
+
529
+ The delta includes changed source coordinates, current obligation text, affected
530
+ native evidence references, missing-link disclosure and exact group targets.
531
+ Unchanged obligations are represented by `validAcknowledgments` and `totalGroups`.
532
+ An empty `groups` array means that receiver has no pending repairs. Evidence link
533
+ presence and receiver understanding retain their separate meanings from `show`.
534
+ Legacy `show` continues to assess the original whole-packet acknowledgment;
535
+ `repair` assesses the receiver's current understanding at group granularity.
536
+
537
+ Renewal JSON supplies the immutable contract `digest` and a nonempty `groups`
538
+ array: each row has `id`, `target`, `questions`, `assumptions` and `evidence` maps.
539
+ Answer exactly that group's obligation keys. Partial group selection is supported.
540
+ Targets bind the contract and SDK-read source revisions, including native update
541
+ coordinates, so replaying older content does not renew a newer revision. Unchanged
542
+ groups need no response. Matching retries and a peer's completed renewal return
543
+ current validity without adding a duplicate receipt. Renewals append native comments
544
+ to the existing contract; no contract copies, sources, claims or separate stores
545
+ are written. Foreign or malformed receipt-shaped comments are skipped with an
546
+ indexed reason by repair/renew and never edited or deleted.
547
+
548
+ Each new acknowledgment stores `dependencies`, an array of per-group snapshots:
549
+ `{ id, items, edges, evidenceLinks }`. Renewals store `items`, `edges` and
550
+ `evidenceLinks` alongside that group's responses and revision target. `items`
551
+ records every covered item id, full SDK-row revision (or null for a missing item),
552
+ status, title and blocker edges. Native edge coordinates (`from`, `to`, `kind`)
553
+ and native evidence-link coordinates (`item`, `kind`, optional `ref`) each carry
554
+ SHA-256 revisions of their complete SDK-read metadata. These inventories come
555
+ from the same certified source read that validates the acknowledgment or renewal.
556
+
557
+ Repair compares the recorded dependency set plus newly reachable dependencies;
558
+ it never drops an already covered item because today's blocker edge disappeared.
559
+ Coverage identities persist across renewals, including transitive dependencies,
560
+ missing items and evidence outside the current focus closure. For example,
561
+ acknowledge A blocked by B with required evidence on B, remove A's blocker edge,
562
+ and renew A: later edits, link removal or deletion of B still invalidate A's
563
+ understanding. A new blocker can add further evidence obligations to a group.
564
+ Known missing evidence remains distinct from readiness, as in the original
565
+ handoff contract. The 64-item coverage limit and token refusal still apply;
566
+ create a new focused contract when retained coverage outgrows that limit.
567
+
568
+ Older acknowledgments without explicit inventories remain readable using the
569
+ immutable contract's item snapshots. Older renewal snapshots are conservatively
570
+ combined with prior coverage so they cannot erase previously covered identities.
571
+ New acknowledgments and renewals append the full inventory; stored history is
572
+ never rewritten to manufacture historical metadata. See the recorded-coverage
573
+ regression and independent graph model in `test/handoff-coverage.test.ts`.
574
+
575
+ The SDK exports `inspectHandoffRepair`, `renewHandoff`, `parseHandoffRenewal` and
576
+ `HandoffRepair`, `HandoffRepairGroup`, `HandoffRepairChange`, `HandoffRenewal`,
577
+ `HandoffRenewalGroup`, `HandoffDependencySet`, `HandoffAcknowledgedGroup`,
578
+ `HandoffCoveredEdge` and `HandoffCoveredEvidence`. Use the existing `HandoffOptions` with `pmRoot`, `author`,
579
+ optional native `client` and `tokenBudget`. Output uses native TOON/JSON and the
580
+ same 4,000-token default ceiling (maximum 64,000). Oversized deltas refuse rather
581
+ than discard obligations. An unacknowledged receiver gets `handoff_unacknowledged`
582
+ and must first acknowledge a fresh contract. Other typed refusals retain the
583
+ existing `HandoffError` codes and actionable remedies; stale renewal exits 3.
584
+
585
+ Renewal holds an SDK token-owned lease from its initial read through append and
586
+ verification, and uses native `comments({ ifAbsent: true })` for atomic append.
587
+ The SDK releases only its owned lease, last. Arbitrary source writers do not join
588
+ this lease: sources are rechecked after append, and a raced renewal refuses stale;
589
+ its historical comment cannot validate the newer revision. A later edit after the
590
+ final verified read appears on the next repair read. See the
591
+ [complete example](docs/examples/handoff-repair.md) and
592
+ [validation evidence](docs/handoff-repair-validation.md).
593
+
498
594
  ## Decision alternatives digest
499
595
 
500
596
  ```bash
@@ -562,10 +658,78 @@ refusals are `invalid` (correct IDs/budget), `missing` (check exact IDs), `track
562
658
  fewer items). CLI refusals exit 2 and retain `alternatives_<code>` and a remedy in
563
659
  the host's expected-error contract. See the [worked example](docs/examples/alternatives.md).
564
660
 
661
+ ## Stakeholder disclosure profiles
662
+
663
+ Render a brief for an explicit audience using native compact TOON (default) or
664
+ JSON. This is a read-only operation and does not require git:
665
+
666
+ ```bash
667
+ pm brief disclose --audience public
668
+ pm --json brief disclose --audience external --dry-run
669
+ pm --json brief disclose --policy disclosure.json --token-budget 8000
670
+ ```
671
+
672
+ | Audience | Permitted brief fields |
673
+ | --- | --- |
674
+ | `public` | Generation time, item count, and ranked item IDs, titles, types, statuses and priorities |
675
+ | `external` | Public fields plus ranking explanations, tags, dependencies, blockers, risks and staleness |
676
+ | `internal` | External fields plus workspace metadata, assignees, required context, activity, recommendations, insights and source budget metadata |
677
+
678
+ All profiles exclude unmodeled fields, including custom fields, momentum,
679
+ governance and merge receipts. Recognized credential-shaped values are removed
680
+ using the core SDK guard. The tracker path applies this guard before ranking
681
+ and compaction so shortening cannot conceal a recognized secret. This reuses
682
+ core detection; it is not a universal credential scanner or a guarantee that
683
+ arbitrary prose contains no confidential information. Review permitted titles
684
+ and labels before sharing them.
685
+
686
+ Policies can only narrow a profile. For example, `disclosure.json`:
687
+
688
+ ```json
689
+ {"profile":"public","exclude":["focus.*.title","next.*.title","decisionsNeeded.*.title"]}
690
+ ```
691
+
692
+ Only `profile` and `exclude` are accepted. Unknown keys, audiences or field
693
+ selectors refuse before reading the tracker. `DisclosureField` in the SDK
694
+ enumerates supported selectors; `*` denotes an array index. There is no override
695
+ for adding custom fields or bypassing the credential guard.
696
+
697
+ Every result contains an exclusion manifest grouped by reason (`profile`,
698
+ `policy`, `secret`, `unknown_field`, `invalid_value`). Each entry maps a
699
+ JSON Pointer path to an occurrence count. Profile/policy paths aggregate array
700
+ indices as `*`; secret paths identify individual rendered occurrences. Unknown
701
+ field names are replaced by `@N`, their zero-based position in their parent
702
+ object's property enumeration. Pre-compaction secret exclusions use
703
+ `/source/N/@M` for record/field positions; `/source/N` means a secret-bearing
704
+ identity caused the whole record to be withheld. These paths describe the
705
+ snapshot and never contain field values, item identifiers or unknown key text.
706
+ Dry runs return the same manifest without any brief values.
707
+
708
+ ```ts
709
+ import { buildBrief, renderDisclosureBrief, buildDisclosureBrief, DisclosureError } from "pm-brief";
710
+
711
+ const brief = buildBrief(items); // One source; multiple independent renderings.
712
+ const publicView = renderDisclosureBrief(brief, { profile: "public" });
713
+ const reviewPreview = renderDisclosureBrief(brief, { profile: "external" }, { dryRun: true });
714
+ // Or read a complete, certified native snapshot using an optional host PmClient:
715
+ const view = await buildDisclosureBrief({ profile: "public" }, { pmRoot: ".agents/pm" });
716
+ ```
717
+
718
+ The native tracker path reuses the existing 4000-token source brief selection;
719
+ `sourceTruncated` discloses source compaction. The default disclosure ceiling is
720
+ 8000 estimated tokens, covering native JSON/TOON framing and every exclusion.
721
+ Use `renderDisclosureBrief` with your own `buildBrief` controls for a different
722
+ source selection. Rendering never silently drops manifest entries to fit.
723
+ `DisclosureError` provides `code` and `remedy`: `policy` (correct the policy),
724
+ `invalid` (correct controls/input), `tracker` (resolve the incomplete/unreadable
725
+ source), or `budget` (increase the ceiling or supply a smaller brief). CLI
726
+ refusals exit 2 with `disclosure_<code>` and a remedy, without source text or
727
+ nested error details. See the [worked example and public-tracker replay](docs/examples/disclosure.md).
728
+
565
729
  ## Without git
566
730
 
567
731
  Briefs, prompts, ranking, history deltas, governance, duplicate checks and all
568
- handoff and decision alternatives commands work in plain initialized trackers without a git executable.
732
+ handoff, decision alternatives and stakeholder disclosure commands work in plain initialized trackers without a git executable.
569
733
  Handoff storage uses the native SDK dispatcher and can reuse a host client.
570
734
  `brief diverge` needs a git repository and git refs. Handoff receipts have no
571
735
  branch, commit or repository dependency.
@@ -0,0 +1,70 @@
1
+ import { PmClient } from "@unbrained/pm-cli/sdk";
2
+ import type { ExtensionApi } from "@unbrained/pm-cli/sdk/authoring";
3
+ import type { AgentBrief } from "./index.ts";
4
+ /** Fixed audiences; callers may narrow a profile but cannot widen it. */
5
+ export type DisclosureProfile = "internal" | "external" | "public";
6
+ /** Brief sections containing the same ranked-item shape. */
7
+ type ItemSection = "focus" | "next" | "decisionsNeeded";
8
+ /** Supported scalar fields in ranked items. */
9
+ type ItemField = "id" | "title" | "type" | "status" | "priority" | "assignee" | "whyNow" | "rankingScore" | "confidence" | "tokenCostEstimate" | "mergeCompromised";
10
+ /** Known selectors, using * for array indices; unknown selectors are refused. */
11
+ export type DisclosureField = "generatedAt" | "workspace.root" | "workspace.pmVersion" | "workspace.itemCount" | "budget.requestedTokens" | "budget.estimatedTokens" | "budget.truncated" | `${ItemSection}.*.${ItemField}` | `${ItemSection}.*.${"tags" | "rankingReasons" | "requiredContext" | "dependencyIds" | "dependentIds"}.*` | `blockers.*.${"itemId" | "blockedBy" | "kind" | "title" | "status"}` | `risks.*.${"itemId" | "severity" | "reason"}` | `staleContext.*.${"itemId" | "title" | "updatedAt" | "daysStale"}` | `recentActivity.*.${"timestamp" | "author" | "operation" | "itemId" | "message"}` | `recommendedPmUpdates.*.${"itemId" | "command" | "reason" | "safeToAutoApply"}` | `insights.*.${"level" | "message" | "suggestion"}`;
12
+ /** Explicit audience and optional additional denials. No permissive extension fields. */
13
+ export interface DisclosurePolicy {
14
+ profile: DisclosureProfile;
15
+ exclude?: DisclosureField[];
16
+ }
17
+ /** JSON values retained after validation and disclosure checks. */
18
+ export type DisclosureValue = string | number | boolean | DisclosureValue[] | {
19
+ [key: string]: DisclosureValue;
20
+ };
21
+ /** Value-free reasons; profile/policy paths use * for all matching array indices. */
22
+ export type DisclosureExclusionReason = "profile" | "policy" | "secret" | "unknown_field" | "invalid_value";
23
+ /** Field-level JSON Pointer paths and occurrence counts grouped by exclusion reason. */
24
+ export type DisclosureExclusion = Record<DisclosureExclusionReason, Record<string, number>>;
25
+ /** Agent-sized rendering with a manifest; dry runs contain no brief values. */
26
+ export interface DisclosureResult {
27
+ protocol: "pm-brief.disclosure/v1";
28
+ profile: DisclosureProfile;
29
+ dryRun: boolean;
30
+ sourceTruncated: boolean;
31
+ brief?: {
32
+ [key: string]: DisclosureValue;
33
+ };
34
+ exclusions: DisclosureExclusion;
35
+ estimatedTokenCeiling: number;
36
+ }
37
+ /** Pure rendering controls; the budget includes the full exclusion manifest. */
38
+ export interface DisclosureRenderOptions {
39
+ dryRun?: boolean;
40
+ tokenBudget?: number;
41
+ }
42
+ /** Native, backend-neutral tracker context; never invokes git or writes records. */
43
+ export interface DisclosureOptions extends DisclosureRenderOptions {
44
+ pmRoot: string;
45
+ client?: PmClient;
46
+ generatedAt?: string;
47
+ }
48
+ /** Stable refusal categories shared by the SDK and native CLI. */
49
+ export type DisclosureRefusalCode = "policy" | "invalid" | "tracker" | "budget";
50
+ /** Expected failure containing no source values, paths, policy text or nested causes. */
51
+ export declare class DisclosureError extends Error {
52
+ /** Stable machine category for recovery logic. */
53
+ readonly code: DisclosureRefusalCode;
54
+ /** Safe action to take before retrying. */
55
+ readonly remedy: string;
56
+ /** Preserve recovery information without exposing the failing input. */
57
+ constructor(code: DisclosureRefusalCode, message: string, remedy: string);
58
+ /** Normalize an unexpected failure without retaining potentially forbidden nested text. */
59
+ static from(error: unknown): DisclosureError;
60
+ }
61
+ /** Validate policy keys and every field selector before any tracker read or render. */
62
+ export declare function parseDisclosurePolicy(value: unknown): DisclosurePolicy;
63
+ /** Render the same brief through a closed field vocabulary before native serialization. */
64
+ export declare function renderDisclosureBrief(brief: AgentBrief, input: DisclosurePolicy, options?: DisclosureRenderOptions): DisclosureResult;
65
+ /** Read a certified native snapshot and reuse pm-brief ranking before disclosure. */
66
+ export declare function buildDisclosureBrief(input: DisclosurePolicy, options: DisclosureOptions): Promise<DisclosureResult>;
67
+ /** Register native structured output and sanitized expected errors, with no git dependency. */
68
+ export declare function registerDisclosureCommand(api: ExtensionApi): void;
69
+ export {};
70
+ //# sourceMappingURL=disclosure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disclosure.d.ts","sourceRoot":"","sources":["../disclosure.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,227 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { PmClient, certifyCompleteListResult, createPmCliExpectedError, estimatePmOutputTokens, readSettings, resolveRuntimeStatusRegistry, scanMutationSecrets } from "@unbrained/pm-cli/sdk";
3
+ import { buildBrief } from "./index.js";
4
+ /** Expected failure containing no source values, paths, policy text or nested causes. */
5
+ export class DisclosureError extends Error {
6
+ /** Stable machine category for recovery logic. */
7
+ code;
8
+ /** Safe action to take before retrying. */
9
+ remedy;
10
+ /** Preserve recovery information without exposing the failing input. */
11
+ constructor(code, message, remedy) {
12
+ super(message);
13
+ this.name = "DisclosureError";
14
+ this.code = code;
15
+ this.remedy = remedy;
16
+ }
17
+ /** Normalize an unexpected failure without retaining potentially forbidden nested text. */
18
+ static from(error) {
19
+ return error instanceof DisclosureError ? error : new DisclosureError("tracker", "Disclosure could not complete", "Run pm health and check tracker permissions before retrying");
20
+ }
21
+ }
22
+ const LEVEL = { public: 0, external: 1, internal: 2 };
23
+ const FIELDS = new Map([
24
+ ["generatedAt", 0], ["workspace.root", 2], ["workspace.pmVersion", 2], ["workspace.itemCount", 0],
25
+ ["budget.requestedTokens", 2], ["budget.estimatedTokens", 2], ["budget.truncated", 2],
26
+ ]);
27
+ for (const section of ["focus", "next", "decisionsNeeded"]) {
28
+ for (const field of ["id", "title", "type", "status", "priority"])
29
+ FIELDS.set(`${section}.*.${field}`, 0);
30
+ for (const field of ["whyNow", "rankingScore", "confidence", "tokenCostEstimate", "mergeCompromised", "tags.*", "rankingReasons.*", "dependencyIds.*", "dependentIds.*"])
31
+ FIELDS.set(`${section}.*.${field}`, 1);
32
+ for (const field of ["assignee", "requiredContext.*"])
33
+ FIELDS.set(`${section}.*.${field}`, 2);
34
+ }
35
+ for (const field of ["itemId", "blockedBy", "kind", "title", "status"])
36
+ FIELDS.set(`blockers.*.${field}`, 1);
37
+ for (const field of ["itemId", "severity", "reason"])
38
+ FIELDS.set(`risks.*.${field}`, 1);
39
+ for (const field of ["itemId", "title", "updatedAt", "daysStale"])
40
+ FIELDS.set(`staleContext.*.${field}`, 1);
41
+ for (const field of ["timestamp", "author", "operation", "itemId", "message"])
42
+ FIELDS.set(`recentActivity.*.${field}`, 2);
43
+ for (const field of ["itemId", "command", "reason", "safeToAutoApply"])
44
+ FIELDS.set(`recommendedPmUpdates.*.${field}`, 2);
45
+ for (const field of ["level", "message", "suggestion"])
46
+ FIELDS.set(`insights.*.${field}`, 2);
47
+ /** Compile only trusted profile selectors; data keys remain exact path segments. */
48
+ const FIELD_PATHS = [...FIELDS].map(([field, level]) => ({ field: field, level, segments: field.split(".") }));
49
+ /** Match a structured data-path prefix; profile wildcards accept only numeric array indices. */
50
+ function matchesDisclosurePath(pattern, path) {
51
+ return path.length <= pattern.length && path.every((segment, i) => pattern[i] === "*" ? typeof segment === "number" : pattern[i] === segment);
52
+ }
53
+ /** Refuse a malformed or widening policy without echoing its contents. */
54
+ function invalidPolicy() {
55
+ throw new DisclosureError("policy", "Unknown or invalid disclosure policy", "Use only profile (internal, external or public) and optional exclude containing documented field selectors; policies can only remove fields");
56
+ }
57
+ /** Check JSON object shape without coercing arrays or null into a policy. */
58
+ function object(value) { return typeof value === "object" && value !== null && !Array.isArray(value); }
59
+ /** Validate policy keys and every field selector before any tracker read or render. */
60
+ export function parseDisclosurePolicy(value) {
61
+ if (!object(value) || !Object.hasOwn(value, "profile") || Reflect.ownKeys(value).some(key => key !== "profile" && key !== "exclude") || typeof value.profile !== "string" || !Object.hasOwn(LEVEL, value.profile))
62
+ return invalidPolicy();
63
+ if (value.exclude !== undefined && (!Array.isArray(value.exclude) || value.exclude.length > FIELDS.size || value.exclude.some(field => typeof field !== "string" || !FIELDS.has(field))))
64
+ return invalidPolicy();
65
+ return { profile: value.profile, exclude: value.exclude === undefined ? [] : [...new Set(value.exclude)] };
66
+ }
67
+ /** Bound the entire native JSON/TOON envelope, including framing and diagnostics. */
68
+ function budget(options) {
69
+ const amount = options.tokenBudget ?? 8000;
70
+ if (!Number.isSafeInteger(amount) || amount < 1 || amount > 64000 || (options.dryRun !== undefined && typeof options.dryRun !== "boolean"))
71
+ throw new DisclosureError("invalid", "Invalid disclosure controls", "Use a boolean dryRun and an integer --token-budget from 1 to 64000 (default 8000)");
72
+ return amount;
73
+ }
74
+ /** Account for the complete manifest after both source and render exclusions. */
75
+ function bounded(result, limit) {
76
+ result.estimatedTokenCeiling = 64000;
77
+ result.estimatedTokenCeiling = estimatePmOutputTokens(Buffer.byteLength(JSON.stringify(result, null, 2)) * 2 + 256);
78
+ if (result.estimatedTokenCeiling > limit)
79
+ throw new DisclosureError("budget", "Disclosure and its exclusion manifest exceed the token budget", "Increase --token-budget (maximum 64000) or supply a smaller brief; no exclusion evidence is silently dropped");
80
+ return result;
81
+ }
82
+ /** Render the same brief through a closed field vocabulary before native serialization. */
83
+ export function renderDisclosureBrief(brief, input, options = {}) {
84
+ const policy = parseDisclosurePolicy(input);
85
+ const limit = budget(options);
86
+ if (!object(brief))
87
+ throw new DisclosureError("invalid", "Invalid brief", "Supply the object returned by buildBrief; arbitrary scalar or array input is not a brief");
88
+ const exclusions = { profile: {}, policy: {}, secret: {}, unknown_field: {}, invalid_value: {} };
89
+ const denied = new Set(policy.exclude);
90
+ const active = new Set();
91
+ /** Aggregate repeated policy paths without source values or redundant per-row metadata. */
92
+ function exclude(reason, path) { exclusions[reason][path] = (exclusions[reason][path] ?? 0) + 1; }
93
+ /** Traverse only known containers; never expose unknown key text or scan diagnostics. */
94
+ function walk(value, segments, path) {
95
+ if (typeof value === "object" && value !== null && active.has(value))
96
+ throw new DisclosureError("invalid", "Invalid recursive brief", "Supply an acyclic buildBrief result; known containers have a fixed vocabulary and nesting shape");
97
+ const matches = FIELD_PATHS.filter(entry => matchesDisclosurePath(entry.segments, segments));
98
+ const exact = matches.find(entry => entry.segments.length === segments.length);
99
+ if (exact !== undefined) {
100
+ const { field, level } = exact;
101
+ if (level > LEVEL[policy.profile]) {
102
+ exclude("profile", `/${field.replaceAll(".", "/")}`);
103
+ return undefined;
104
+ }
105
+ if (denied.has(field)) {
106
+ exclude("policy", `/${field.replaceAll(".", "/")}`);
107
+ return undefined;
108
+ }
109
+ if (!(typeof value === "string" || typeof value === "boolean" || (typeof value === "number" && Number.isFinite(value)))) {
110
+ exclude("invalid_value", path);
111
+ return undefined;
112
+ }
113
+ if (scanMutationSecrets(value).length > 0) {
114
+ exclude("secret", path);
115
+ return undefined;
116
+ }
117
+ return value;
118
+ }
119
+ if (matches.length === 0) {
120
+ exclude("unknown_field", path);
121
+ return undefined;
122
+ }
123
+ if (Array.isArray(value)) {
124
+ active.add(value);
125
+ const result = [];
126
+ for (let i = 0; i < value.length; i++) {
127
+ const entry = walk(value[i], [...segments, i], `${path}/${i}`);
128
+ if (entry !== undefined)
129
+ result.push(entry);
130
+ }
131
+ active.delete(value);
132
+ return result;
133
+ }
134
+ if (object(value)) {
135
+ active.add(value);
136
+ const result = {};
137
+ for (const [i, [key, entry]] of Object.entries(value).entries()) {
138
+ if (entry === undefined)
139
+ continue;
140
+ const child = [...segments, key];
141
+ const known = FIELD_PATHS.some(field => matchesDisclosurePath(field.segments, child));
142
+ const rendered = walk(entry, child, `${path}/${known ? key : `@${i}`}`);
143
+ if (rendered !== undefined)
144
+ result[key] = rendered;
145
+ }
146
+ active.delete(value);
147
+ return result;
148
+ }
149
+ exclude("invalid_value", path);
150
+ return undefined;
151
+ }
152
+ const filtered = walk(brief, [], "");
153
+ const result = { protocol: "pm-brief.disclosure/v1", profile: policy.profile, dryRun: options.dryRun ?? false, sourceTruncated: brief.budget?.truncated === true, exclusions, estimatedTokenCeiling: 64000 };
154
+ if (!result.dryRun)
155
+ result.brief = filtered;
156
+ return bounded(result, limit);
157
+ }
158
+ /** Read a certified native snapshot and reuse pm-brief ranking before disclosure. */
159
+ export async function buildDisclosureBrief(input, options) {
160
+ const policy = parseDisclosurePolicy(input);
161
+ budget(options);
162
+ let brief;
163
+ const sourceSecrets = {};
164
+ try {
165
+ const client = options.client ?? new PmClient({ pmRoot: options.pmRoot, noExtensions: true });
166
+ const items = certifyCompleteListResult(await client.listAllComplete({ includeBody: true })).items;
167
+ // Guard before compaction: a shortened credential may no longer match its detector.
168
+ const protectedItems = items.flatMap((item, i) => {
169
+ if (scanMutationSecrets(item.id).length) {
170
+ sourceSecrets[`/source/${i}`] = 1;
171
+ return [];
172
+ }
173
+ const safe = { ...item };
174
+ for (const [j, [field, value]] of Object.entries(item).entries()) {
175
+ if (scanMutationSecrets(value).length) {
176
+ delete safe[field];
177
+ sourceSecrets[`/source/${i}/@${j}`] = 1;
178
+ }
179
+ }
180
+ return [safe];
181
+ });
182
+ const statusRegistry = resolveRuntimeStatusRegistry((await readSettings(options.pmRoot)).schema);
183
+ brief = buildBrief(protectedItems, { pmRoot: ".agents/pm", generatedAt: options.generatedAt, statusRegistry });
184
+ }
185
+ catch {
186
+ throw new DisclosureError("tracker", "Cannot build a certified disclosure brief", "Run pm health and resolve unreadable or incomplete records before retrying");
187
+ }
188
+ const result = renderDisclosureBrief(brief, policy, { ...options, tokenBudget: 64000 });
189
+ Object.assign(result.exclusions.secret, sourceSecrets);
190
+ return bounded(result, budget(options));
191
+ }
192
+ /** Register native structured output and sanitized expected errors, with no git dependency. */
193
+ export function registerDisclosureCommand(api) {
194
+ api.registerCommand({
195
+ name: "brief disclose",
196
+ description: "Render a brief for an explicit stakeholder profile with a value-free exclusion manifest",
197
+ flags: [
198
+ { long: "--audience", type: "string", value_name: "audience", description: "Required audience: internal, external or public (or supply --policy)" },
199
+ { long: "--policy", type: "string", value_name: "file", description: "JSON policy containing profile and optional exclude; cannot widen a profile" },
200
+ { long: "--dry-run", type: "boolean", description: "Explain exclusions without returning brief values" },
201
+ { long: "--token-budget", type: "string", value_name: "n", description: "Conservative complete JSON/TOON ceiling (default 8000; maximum 64000)" },
202
+ ],
203
+ async run(ctx) {
204
+ try {
205
+ if (ctx.args.length || (ctx.options.audience !== undefined && ctx.options.policy !== undefined))
206
+ return invalidPolicy();
207
+ let policy;
208
+ if (ctx.options.policy !== undefined) {
209
+ try {
210
+ policy = parseDisclosurePolicy(JSON.parse(await readFile(String(ctx.options.policy), "utf8")));
211
+ }
212
+ catch {
213
+ return invalidPolicy();
214
+ }
215
+ }
216
+ else
217
+ policy = parseDisclosurePolicy({ profile: ctx.options.audience });
218
+ return await buildDisclosureBrief(policy, { pmRoot: ctx.pm_root, client: ctx.sdk?.client, dryRun: ctx.options.dryRun, tokenBudget: ctx.options.tokenBudget === undefined ? undefined : Number(ctx.options.tokenBudget) });
219
+ }
220
+ catch (error) {
221
+ const refusal = DisclosureError.from(error);
222
+ throw createPmCliExpectedError(`disclosure ${refusal.code}: ${refusal.message}. Remedy: ${refusal.remedy}`, { exitCode: 2, context: { code: `disclosure_${refusal.code}`, required: refusal.remedy } });
223
+ }
224
+ },
225
+ });
226
+ }
227
+ //# sourceMappingURL=disclosure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disclosure.js","sourceRoot":"","sources":["../disclosure.ts"],"names":[],"mappings":"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"}