@peasant-labs/fairtrade 0.0.7 → 0.0.9

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.
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Comprehension-debt state resolution over MapNode scalars only (no per-hunk
3
+ * wire data required; the formula is pure over ReadState plus the three
4
+ * region-coverage counts).
5
+ * @param {RankInputNode} node
6
+ * @returns {DebtState}
7
+ */
8
+ export function debtState(node: RankInputNode): DebtState;
9
+ /**
10
+ * Comprehension-debt magnitude. `state` must be the value `debtState(node)` returned for
11
+ * the SAME node (kept as a parameter, not recomputed, so callers that already
12
+ * branched on `debtState` never pay for or risk re-deriving it differently).
13
+ * @param {RankInputNode} node @param {DebtState} state
14
+ * @returns {number}
15
+ */
16
+ export function debt(node: RankInputNode, state: DebtState): number;
17
+ /** `coverage`: an unattributable hunk caps it strictly below 1 (COVERAGE_CAP). @param {RankInputNode} node */
18
+ export function coverage(node: RankInputNode): number;
19
+ /** `hunkClears`: the named state gate, never shadowed by a fallback. @param {RankInputNode} node */
20
+ export function hunkClears(node: RankInputNode): boolean;
21
+ /**
22
+ * The path-conditioned partial-read hover copy. Returns null
23
+ * for every non-`partial-read` state. Callers only call this after checking
24
+ * `debtState(node) === 'partial-read'`.
25
+ * @param {RankInputNode} node
26
+ * @returns {string|null}
27
+ */
28
+ export function partialReadHoverText(node: RankInputNode): string | null;
29
+ /**
30
+ * State-specific honesty copy for every visible debt tag. The copy describes
31
+ * recorded evidence and always remains a prompt, never a claim about a person.
32
+ * @param {RankInputNode} node
33
+ * @param {DebtState} state
34
+ * @returns {string|null}
35
+ */
36
+ export function debtHoverText(node: RankInputNode, state: DebtState): string | null;
37
+ /**
38
+ * Up to two scent tags per row, including the softened `viewed`
39
+ * treatment and the multi-state debt vocabulary. The `partial-read` state
40
+ * reuses the strong/softened tag with the path-conditioned hover. No new
41
+ * tag for the partial state.
42
+ * @param {RankInputNode} node @param {DebtState} state @param {{focusId?:string|null, parentOf?:Map<string,string|null>, distanceToFocus?:number|null, maxTouch?:number, hoveredOrSelectedSessionId?:string|null}} [context]
43
+ * @returns {string[]}
44
+ */
45
+ export function scentTagsFor(node: RankInputNode, state: DebtState, context?: {
46
+ focusId?: string | null;
47
+ parentOf?: Map<string, string | null>;
48
+ distanceToFocus?: number | null;
49
+ maxTouch?: number;
50
+ hoveredOrSelectedSessionId?: string | null;
51
+ }): string[];
52
+ /**
53
+ * Computes only payload/rank-mode intrinsic terms. A caller can memoize this
54
+ * object by node-array identity and rank mode; focus, filter, hover and session
55
+ * selection belong exclusively to `deriveRankedRows` below.
56
+ * @param {RankInputNode[]} nodes
57
+ * @param {{rankMode?: RankMode, nowMs?: number}} [options]
58
+ * @returns {IntrinsicRanking}
59
+ */
60
+ export function rankMapNodesIntrinsic(nodes: RankInputNode[], options?: {
61
+ rankMode?: RankMode;
62
+ nowMs?: number;
63
+ }): IntrinsicRanking;
64
+ /**
65
+ * Applies focus distance, active-session scent, sort, and filter to memoized
66
+ * intrinsic terms. Ties break by node id; all-equal intrinsic terms stay 0.
67
+ * @param {IntrinsicRanking} intrinsicRanking
68
+ * @param {{focusId?: string|null, scentFilter?: string|null, hoveredOrSelectedSessionId?: string|null}} [options]
69
+ * @returns {RankedRow[]}
70
+ */
71
+ export function deriveRankedRows(intrinsicRanking: IntrinsicRanking, options?: {
72
+ focusId?: string | null;
73
+ scentFilter?: string | null;
74
+ hoveredOrSelectedSessionId?: string | null;
75
+ }): RankedRow[];
76
+ /** Compatibility composition of the public two-phase ranking API.
77
+ * @param {RankInputNode[]} nodes
78
+ * @param {{rankMode?: RankMode, focusId?: string|null, scentFilter?: string|null, hoveredOrSelectedSessionId?: string|null, nowMs?: number}} [options]
79
+ */
80
+ export function rankMapNodes(nodes: RankInputNode[], options?: {
81
+ rankMode?: RankMode;
82
+ focusId?: string | null;
83
+ scentFilter?: string | null;
84
+ hoveredOrSelectedSessionId?: string | null;
85
+ nowMs?: number;
86
+ }): RankedRow[];
87
+ /**
88
+ * Threshold gating: show `DOI >= max(0.25, 0.5*maxDOI)`, floor 5, cap 25,
89
+ * then a single "show all N files" expander. Deterministic, fixture-pinnable.
90
+ * In debt mode, known debt is included before thresholded unknown/clear rows,
91
+ * so threshold and cap gating cannot hide actionable evidence behind unknowns.
92
+ * @param {RankedRow[]} rows @param {{expanded?: boolean, rankMode?:RankMode}} [options]
93
+ * @returns {{visible: RankedRow[], total: number, overflowCount: number}}
94
+ */
95
+ export function gateRankedRows(rows: RankedRow[], options?: {
96
+ expanded?: boolean;
97
+ rankMode?: RankMode;
98
+ }): {
99
+ visible: RankedRow[];
100
+ total: number;
101
+ overflowCount: number;
102
+ };
103
+ /** @typedef {import('@peasant-labs/schema').ReadAttributionState} ReadAttributionState */
104
+ /** @typedef {import('@peasant-labs/schema').ReadStateGrade} ReadStateGrade */
105
+ /** @typedef {'relevance'|'debt'|'churn'} RankMode */
106
+ /** @typedef {'unknown'|'none'|'reviewed'|'partial-read'|'viewed'|'no-recorded-read'} DebtState */
107
+ /**
108
+ * One node's ranking-relevant scalars. Every field is read-only input; nothing
109
+ * here is mutated. `lastTouchMs` and `parent` are optional client-side hints
110
+ * hints. An absent value means "no recency/tree-focus
111
+ * signal", never a fabricated 0.
112
+ * @typedef {object} RankInputNode
113
+ * @property {string} id
114
+ * @property {string} name
115
+ * @property {number} touchCount
116
+ * @property {number} effortDensity - 0..1
117
+ * @property {number} agentEditedCount
118
+ * @property {number} readCount
119
+ * @property {ReadAttributionState} readAttribution
120
+ * @property {ReadStateGrade} readState - composed effective read-state grade for the CURRENT content version
121
+ * @property {number} changedRegionCount - total changed regions (Hall)
122
+ * @property {number} attributedRegionCount - attributed regions (H, M)
123
+ * @property {number} reviewedRegionCount - reviewed-of-attributed regions (N)
124
+ * @property {number} [lastTouchMs]
125
+ * @property {string|null} [parent]
126
+ * @property {string|null} [recentSessionId] - the session that most recently edited this node, if known
127
+ */
128
+ /** @typedef {{id:string, name:string, doi:number, debtState:DebtState, debt:number, coverage:number, hunkClears:boolean, scentTags:string[], hoverText:string|null}} RankedRow */
129
+ /** @typedef {{node:RankInputNode, intrinsic:number, debtState:DebtState, debt:number, coverage:number, hunkClears:boolean, hoverText:string|null}} IntrinsicRankedNode */
130
+ /** @typedef {{rankMode:RankMode, rows:IntrinsicRankedNode[], parentOf:Map<string,string|null>, maxTouch:number}} IntrinsicRanking */
131
+ /** DOI (degree-of-interest) term weights. Sum to 1.0 and are fixture-pinned. */
132
+ export const DOI_WEIGHTS: Readonly<{
133
+ touch: 0.35;
134
+ effortDensity: 0.25;
135
+ debt: 0.25;
136
+ recency: 0.15;
137
+ }>;
138
+ /** Comprehension-debt constants, declared beside DOI_WEIGHTS per the frozen contract. */
139
+ export const DEBT_VIEWED: 0.5;
140
+ export const COVERAGE_CAP: 0.9;
141
+ /** Recency half-life, days. */
142
+ export const RECENCY_HALF_LIFE_DAYS: 14;
143
+ /** Threshold-gating constants. */
144
+ export const RANK_FLOOR: 5;
145
+ export const RANK_CAP: 25;
146
+ /**
147
+ * The seven-member scent-tag closed set. Exhaustiveness is enforced by
148
+ * `code-map-ranking.yaml`'s guard: every member must have at least one
149
+ * derivation case, so a future eighth tag without a case reddens.
150
+ * @type {readonly string[]}
151
+ */
152
+ export const SCENT_TAGS: readonly string[];
153
+ export type ReadAttributionState = import("@peasant-labs/schema").ReadAttributionState;
154
+ export type ReadStateGrade = import("@peasant-labs/schema").ReadStateGrade;
155
+ export type RankMode = "relevance" | "debt" | "churn";
156
+ export type DebtState = "unknown" | "none" | "reviewed" | "partial-read" | "viewed" | "no-recorded-read";
157
+ /**
158
+ * One node's ranking-relevant scalars. Every field is read-only input; nothing
159
+ * here is mutated. `lastTouchMs` and `parent` are optional client-side hints
160
+ * hints. An absent value means "no recency/tree-focus
161
+ * signal", never a fabricated 0.
162
+ */
163
+ export type RankInputNode = {
164
+ id: string;
165
+ name: string;
166
+ touchCount: number;
167
+ /**
168
+ * - 0..1
169
+ */
170
+ effortDensity: number;
171
+ agentEditedCount: number;
172
+ readCount: number;
173
+ readAttribution: ReadAttributionState;
174
+ /**
175
+ * - composed effective read-state grade for the CURRENT content version
176
+ */
177
+ readState: ReadStateGrade;
178
+ /**
179
+ * - total changed regions (Hall)
180
+ */
181
+ changedRegionCount: number;
182
+ /**
183
+ * - attributed regions (H, M)
184
+ */
185
+ attributedRegionCount: number;
186
+ /**
187
+ * - reviewed-of-attributed regions (N)
188
+ */
189
+ reviewedRegionCount: number;
190
+ lastTouchMs?: number;
191
+ parent?: string | null;
192
+ /**
193
+ * - the session that most recently edited this node, if known
194
+ */
195
+ recentSessionId?: string | null;
196
+ };
197
+ export type RankedRow = {
198
+ id: string;
199
+ name: string;
200
+ doi: number;
201
+ debtState: DebtState;
202
+ debt: number;
203
+ coverage: number;
204
+ hunkClears: boolean;
205
+ scentTags: string[];
206
+ hoverText: string | null;
207
+ };
208
+ export type IntrinsicRankedNode = {
209
+ node: RankInputNode;
210
+ intrinsic: number;
211
+ debtState: DebtState;
212
+ debt: number;
213
+ coverage: number;
214
+ hunkClears: boolean;
215
+ hoverText: string | null;
216
+ };
217
+ export type IntrinsicRanking = {
218
+ rankMode: RankMode;
219
+ rows: IntrinsicRankedNode[];
220
+ parentOf: Map<string, string | null>;
221
+ maxTouch: number;
222
+ };