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 +34 -7
- package/README.md +169 -5
- package/dist/disclosure.d.ts +70 -0
- package/dist/disclosure.d.ts.map +1 -0
- package/dist/disclosure.js +227 -0
- package/dist/disclosure.js.map +1 -0
- package/dist/handoff.d.ts +73 -1
- package/dist/handoff.d.ts.map +1 -1
- package/dist/handoff.js +285 -10
- package/dist/handoff.js.map +1 -1
- package/dist/index.d.ts +15 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +111 -58
- package/dist/index.js.map +1 -1
- package/docs/examples/disclosure.md +127 -0
- package/docs/examples/handoff-repair.md +39 -0
- package/manifest.json +1 -1
- package/package.json +10 -6
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(
|
|
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.
|
|
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
|
|
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
|
|
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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"}
|