@sentropic/track 0.1.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 (127) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +84 -0
  3. package/dist/accept/index.d.ts +3 -0
  4. package/dist/accept/index.d.ts.map +1 -0
  5. package/dist/accept/index.js +5 -0
  6. package/dist/accept/index.js.map +1 -0
  7. package/dist/accept/ingest.d.ts +16 -0
  8. package/dist/accept/ingest.d.ts.map +1 -0
  9. package/dist/accept/ingest.js +60 -0
  10. package/dist/accept/ingest.js.map +1 -0
  11. package/dist/accept/status.d.ts +15 -0
  12. package/dist/accept/status.d.ts.map +1 -0
  13. package/dist/accept/status.js +44 -0
  14. package/dist/accept/status.js.map +1 -0
  15. package/dist/branch/index.d.ts +2 -0
  16. package/dist/branch/index.d.ts.map +1 -0
  17. package/dist/branch/index.js +3 -0
  18. package/dist/branch/index.js.map +1 -0
  19. package/dist/branch/parse.d.ts +31 -0
  20. package/dist/branch/parse.d.ts.map +1 -0
  21. package/dist/branch/parse.js +116 -0
  22. package/dist/branch/parse.js.map +1 -0
  23. package/dist/cli/desync.d.ts +14 -0
  24. package/dist/cli/desync.d.ts.map +1 -0
  25. package/dist/cli/desync.js +35 -0
  26. package/dist/cli/desync.js.map +1 -0
  27. package/dist/cli/index.d.ts +8 -0
  28. package/dist/cli/index.d.ts.map +1 -0
  29. package/dist/cli/index.js +402 -0
  30. package/dist/cli/index.js.map +1 -0
  31. package/dist/events/canonical.d.ts +5 -0
  32. package/dist/events/canonical.d.ts.map +1 -0
  33. package/dist/events/canonical.js +134 -0
  34. package/dist/events/canonical.js.map +1 -0
  35. package/dist/events/frame.d.ts +11 -0
  36. package/dist/events/frame.d.ts.map +1 -0
  37. package/dist/events/frame.js +19 -0
  38. package/dist/events/frame.js.map +1 -0
  39. package/dist/events/head.d.ts +21 -0
  40. package/dist/events/head.d.ts.map +1 -0
  41. package/dist/events/head.js +54 -0
  42. package/dist/events/head.js.map +1 -0
  43. package/dist/events/index.d.ts +7 -0
  44. package/dist/events/index.d.ts.map +1 -0
  45. package/dist/events/index.js +9 -0
  46. package/dist/events/index.js.map +1 -0
  47. package/dist/events/store.d.ts +33 -0
  48. package/dist/events/store.d.ts.map +1 -0
  49. package/dist/events/store.js +121 -0
  50. package/dist/events/store.js.map +1 -0
  51. package/dist/events/types.d.ts +42 -0
  52. package/dist/events/types.d.ts.map +1 -0
  53. package/dist/events/types.js +22 -0
  54. package/dist/events/types.js.map +1 -0
  55. package/dist/events/validate.d.ts +72 -0
  56. package/dist/events/validate.d.ts.map +1 -0
  57. package/dist/events/validate.js +210 -0
  58. package/dist/events/validate.js.map +1 -0
  59. package/dist/index.d.ts +10 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +11 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/model/acceptance.d.ts +60 -0
  64. package/dist/model/acceptance.d.ts.map +1 -0
  65. package/dist/model/acceptance.js +2 -0
  66. package/dist/model/acceptance.js.map +1 -0
  67. package/dist/model/blocker.d.ts +33 -0
  68. package/dist/model/blocker.d.ts.map +1 -0
  69. package/dist/model/blocker.js +15 -0
  70. package/dist/model/blocker.js.map +1 -0
  71. package/dist/model/decision.d.ts +59 -0
  72. package/dist/model/decision.d.ts.map +1 -0
  73. package/dist/model/decision.js +17 -0
  74. package/dist/model/decision.js.map +1 -0
  75. package/dist/model/index.d.ts +6 -0
  76. package/dist/model/index.d.ts.map +1 -0
  77. package/dist/model/index.js +7 -0
  78. package/dist/model/index.js.map +1 -0
  79. package/dist/model/item.d.ts +51 -0
  80. package/dist/model/item.d.ts.map +1 -0
  81. package/dist/model/item.js +42 -0
  82. package/dist/model/item.js.map +1 -0
  83. package/dist/model/priority.d.ts +22 -0
  84. package/dist/model/priority.d.ts.map +1 -0
  85. package/dist/model/priority.js +13 -0
  86. package/dist/model/priority.js.map +1 -0
  87. package/dist/priority/index.d.ts +2 -0
  88. package/dist/priority/index.d.ts.map +1 -0
  89. package/dist/priority/index.js +4 -0
  90. package/dist/priority/index.js.map +1 -0
  91. package/dist/report/buckets.d.ts +18 -0
  92. package/dist/report/buckets.d.ts.map +1 -0
  93. package/dist/report/buckets.js +24 -0
  94. package/dist/report/buckets.js.map +1 -0
  95. package/dist/report/build.d.ts +44 -0
  96. package/dist/report/build.d.ts.map +1 -0
  97. package/dist/report/build.js +62 -0
  98. package/dist/report/build.js.map +1 -0
  99. package/dist/report/format.d.ts +5 -0
  100. package/dist/report/format.d.ts.map +1 -0
  101. package/dist/report/format.js +81 -0
  102. package/dist/report/format.js.map +1 -0
  103. package/dist/report/index.d.ts +4 -0
  104. package/dist/report/index.d.ts.map +1 -0
  105. package/dist/report/index.js +5 -0
  106. package/dist/report/index.js.map +1 -0
  107. package/dist/state/fold.d.ts +25 -0
  108. package/dist/state/fold.d.ts.map +1 -0
  109. package/dist/state/fold.js +208 -0
  110. package/dist/state/fold.js.map +1 -0
  111. package/dist/state/index.d.ts +3 -0
  112. package/dist/state/index.d.ts.map +1 -0
  113. package/dist/state/index.js +4 -0
  114. package/dist/state/index.js.map +1 -0
  115. package/dist/state/snapshot.d.ts +27 -0
  116. package/dist/state/snapshot.d.ts.map +1 -0
  117. package/dist/state/snapshot.js +49 -0
  118. package/dist/state/snapshot.js.map +1 -0
  119. package/dist/track.d.ts +118 -0
  120. package/dist/track.d.ts.map +1 -0
  121. package/dist/track.js +450 -0
  122. package/dist/track.js.map +1 -0
  123. package/dist/version.d.ts +2 -0
  124. package/dist/version.d.ts.map +1 -0
  125. package/dist/version.js +2 -0
  126. package/dist/version.js.map +1 -0
  127. package/package.json +58 -0
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ // Public barrel for @sentropic/track. Surfaces grow per lot (events, model, state, report, branch).
2
+ export { VERSION } from './version.js';
3
+ export * from './events/index.js';
4
+ export * from './model/index.js';
5
+ export * from './state/index.js';
6
+ export * from './accept/index.js';
7
+ export * from './report/index.js';
8
+ export * from './branch/index.js';
9
+ export { Track } from './track.js';
10
+ export { runCli } from './cli/index.js';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,OAAO,EAAE,KAAK,EAA+D,MAAM,YAAY,CAAA;AAC/F,OAAO,EAAE,MAAM,EAAc,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1,60 @@
1
+ import type { ItemId } from './item.js';
2
+ export type EvidenceKind = 'unit' | 'integration' | 'e2e' | 'manual';
3
+ export type RunResult = 'pass' | 'fail';
4
+ /** Computed per-criterion status (SPEC §2.4). */
5
+ export type CriterionStatus = 'fail' | 'waived' | 'unknown' | 'stale' | 'pass';
6
+ /** Computed per-item acceptance (SPEC §2.4). `n/a` for a Decision (no acceptance axis). */
7
+ export type AcceptanceStatus = CriterionStatus | 'n/a';
8
+ export interface TestRun {
9
+ evidenceId: string;
10
+ commit: string;
11
+ env: string;
12
+ runner: string;
13
+ result: RunResult;
14
+ at: string;
15
+ }
16
+ export interface Waiver {
17
+ criterionId: string;
18
+ reason: string;
19
+ by: string;
20
+ at: string;
21
+ }
22
+ export interface CriterionState {
23
+ id: string;
24
+ itemId: ItemId;
25
+ statement: string;
26
+ waiver?: Waiver;
27
+ }
28
+ export interface EvidenceState {
29
+ id: string;
30
+ criterionId: string;
31
+ kind: EvidenceKind;
32
+ locator: string;
33
+ latestRun?: TestRun;
34
+ }
35
+ export interface CriterionAddedPayload {
36
+ criterionId: string;
37
+ itemId: ItemId;
38
+ statement: string;
39
+ }
40
+ export interface EvidenceLinkedPayload {
41
+ evidenceId: string;
42
+ criterionId: string;
43
+ kind: EvidenceKind;
44
+ locator: string;
45
+ }
46
+ export interface RunPayload {
47
+ evidenceId: string;
48
+ commit: string;
49
+ env: string;
50
+ runner: string;
51
+ result: RunResult;
52
+ at: string;
53
+ }
54
+ export interface WaivedPayload {
55
+ criterionId: string;
56
+ reason: string;
57
+ by: string;
58
+ at: string;
59
+ }
60
+ //# sourceMappingURL=acceptance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acceptance.d.ts","sourceRoot":"","sources":["../../src/model/acceptance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAEvC,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,aAAa,GAAG,KAAK,GAAG,QAAQ,CAAA;AACpE,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,CAAA;AAEvC,iDAAiD;AACjD,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAA;AAC9E,2FAA2F;AAC3F,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAAG,KAAK,CAAA;AAEtD,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,SAAS,CAAA;IACjB,EAAE,EAAE,MAAM,CAAA;CACX;AAED,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;CACX;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,YAAY,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,YAAY,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,SAAS,CAAA;IACjB,EAAE,EAAE,MAAM,CAAA;CACX;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;CACX"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=acceptance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acceptance.js","sourceRoot":"","sources":["../../src/model/acceptance.ts"],"names":[],"mappings":""}
@@ -0,0 +1,33 @@
1
+ import { type BlockerId, type ItemId } from './item.js';
2
+ import type { ActorId } from '../events/types.js';
3
+ export type BlockerKind = 'decision' | 'dependency';
4
+ export type ResolutionRule = 'linked-done' | 'linked-accepted' | 'manual';
5
+ export interface BlockerState {
6
+ id: BlockerId;
7
+ targetId: ItemId;
8
+ kind: BlockerKind;
9
+ ref: ItemId;
10
+ reason: string;
11
+ resolutionRule?: ResolutionRule;
12
+ owner?: ActorId;
13
+ openedAt: string;
14
+ resolvedAt?: string;
15
+ resolvedByEvent: boolean;
16
+ open: boolean;
17
+ }
18
+ export interface BlockerOpenedPayload {
19
+ blockerId: BlockerId;
20
+ targetId: ItemId;
21
+ kind: BlockerKind;
22
+ ref: ItemId;
23
+ reason: string;
24
+ resolutionRule?: ResolutionRule;
25
+ owner?: ActorId;
26
+ }
27
+ /**
28
+ * Manual `blocker resolve` is allowed ONLY for a `manual` dependency blocker (SPEC §2.9).
29
+ * A `decision` blocker resolves only on its Decision's outcome; a `linked-done`/`linked-accepted`
30
+ * dependency blocker auto-resolves when its rule is met. Both reject manual resolution.
31
+ */
32
+ export declare function assertManualResolve(blocker: BlockerState): void;
33
+ //# sourceMappingURL=blocker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blocker.d.ts","sourceRoot":"","sources":["../../src/model/blocker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,SAAS,EAAE,KAAK,MAAM,EAAE,MAAM,WAAW,CAAA;AACpE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAEjD,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,YAAY,CAAA;AACnD,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,iBAAiB,GAAG,QAAQ,CAAA;AAEzE,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,SAAS,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,WAAW,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,eAAe,EAAE,OAAO,CAAA;IACxB,IAAI,EAAE,OAAO,CAAA;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,SAAS,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,WAAW,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAW/D"}
@@ -0,0 +1,15 @@
1
+ import { DomainError } from './item.js';
2
+ /**
3
+ * Manual `blocker resolve` is allowed ONLY for a `manual` dependency blocker (SPEC §2.9).
4
+ * A `decision` blocker resolves only on its Decision's outcome; a `linked-done`/`linked-accepted`
5
+ * dependency blocker auto-resolves when its rule is met. Both reject manual resolution.
6
+ */
7
+ export function assertManualResolve(blocker) {
8
+ if (blocker.kind === 'decision') {
9
+ throw new DomainError(`cannot manually resolve a decision blocker (${blocker.id}); it resolves on the decision outcome`);
10
+ }
11
+ if (blocker.resolutionRule !== 'manual') {
12
+ throw new DomainError(`cannot manually resolve a '${blocker.resolutionRule ?? 'linked-done'}' dependency blocker (${blocker.id})`);
13
+ }
14
+ }
15
+ //# sourceMappingURL=blocker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blocker.js","sourceRoot":"","sources":["../../src/model/blocker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAA+B,MAAM,WAAW,CAAA;AA8BpE;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAqB;IACvD,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAChC,MAAM,IAAI,WAAW,CACnB,+CAA+C,OAAO,CAAC,EAAE,wCAAwC,CAClG,CAAA;IACH,CAAC;IACD,IAAI,OAAO,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;QACxC,MAAM,IAAI,WAAW,CACnB,8BAA8B,OAAO,CAAC,cAAc,IAAI,aAAa,yBAAyB,OAAO,CAAC,EAAE,GAAG,CAC5G,CAAA;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,59 @@
1
+ import { type Gate, type ItemId, type Link, type Realization } from './item.js';
2
+ import type { PriorityAssessment } from './priority.js';
3
+ export type DecisionKind = Gate;
4
+ export type Outcome = 'pending' | 'go' | 'no-go' | 'deferred';
5
+ export interface Option {
6
+ id: string;
7
+ title: string;
8
+ summary: string;
9
+ pros?: string[];
10
+ cons?: string[];
11
+ }
12
+ export interface QAEntry {
13
+ id: string;
14
+ question: string;
15
+ answer?: string;
16
+ }
17
+ /** Typed decision dossier (SPEC §2.7). `outcome` is NOT duplicated here (single source = the Decision). */
18
+ export interface Dossier {
19
+ context: string;
20
+ options: Option[];
21
+ qa: QAEntry[];
22
+ selectedOptionId?: string;
23
+ recommendation?: {
24
+ optionId: string;
25
+ rationale: string;
26
+ };
27
+ resultingSpecChange?: string;
28
+ decisionEvaluation?: PriorityAssessment;
29
+ }
30
+ /** A Decision is a specialized Item (kind:"decision"): only realization (its prep) + outcome (SPEC §2.5). */
31
+ export interface DecisionState {
32
+ id: ItemId;
33
+ kind: 'decision';
34
+ title: string;
35
+ workspace: string;
36
+ realization: Realization;
37
+ decisionKind: DecisionKind;
38
+ targets: ItemId[];
39
+ outcome: Outcome;
40
+ dossier: Dossier;
41
+ parentId?: ItemId;
42
+ sourceKey?: string;
43
+ body?: string;
44
+ links?: Link[];
45
+ }
46
+ export interface DecisionCreatedPayload {
47
+ decisionKind: DecisionKind;
48
+ title: string;
49
+ workspace: string;
50
+ targets: ItemId[];
51
+ dossier: Dossier;
52
+ parentId?: ItemId;
53
+ sourceKey?: string;
54
+ body?: string;
55
+ links?: Link[];
56
+ }
57
+ export declare function assertOutcomeTransition(current: Outcome, to: Outcome): void;
58
+ export declare function isSettled(outcome: Outcome): boolean;
59
+ //# sourceMappingURL=decision.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision.d.ts","sourceRoot":"","sources":["../../src/model/decision.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,IAAI,EACT,KAAK,MAAM,EACX,KAAK,IAAI,EACT,KAAK,WAAW,EACjB,MAAM,WAAW,CAAA;AAClB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAEvD,MAAM,MAAM,YAAY,GAAG,IAAI,CAAA;AAC/B,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,GAAG,UAAU,CAAA;AAE7D,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,2GAA2G;AAC3G,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,EAAE,EAAE,OAAO,EAAE,CAAA;IACb,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,cAAc,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;IACxD,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,kBAAkB,CAAC,EAAE,kBAAkB,CAAA;CACxC;AAED,6GAA6G;AAC7G,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,UAAU,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,WAAW,CAAA;IACxB,YAAY,EAAE,YAAY,CAAA;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,YAAY,CAAA;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;CACf;AAUD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,GAAG,IAAI,CAI3E;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAEnD"}
@@ -0,0 +1,17 @@
1
+ import { DomainError, } from './item.js';
2
+ // outcome machine (SPEC §2.6): pending → {go,no-go,deferred}; deferred → {go,no-go}; go/no-go terminal.
3
+ const OUTCOME_TRANSITIONS = {
4
+ pending: ['go', 'no-go', 'deferred'],
5
+ deferred: ['go', 'no-go'],
6
+ go: [],
7
+ 'no-go': [],
8
+ };
9
+ export function assertOutcomeTransition(current, to) {
10
+ if (!OUTCOME_TRANSITIONS[current].includes(to)) {
11
+ throw new DomainError(`illegal outcome transition ${current} -> ${to}`);
12
+ }
13
+ }
14
+ export function isSettled(outcome) {
15
+ return outcome === 'go' || outcome === 'no-go';
16
+ }
17
+ //# sourceMappingURL=decision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision.js","sourceRoot":"","sources":["../../src/model/decision.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,GAKZ,MAAM,WAAW,CAAA;AA4DlB,wGAAwG;AACxG,MAAM,mBAAmB,GAA4C;IACnE,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC;IACpC,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC;IACzB,EAAE,EAAE,EAAE;IACN,OAAO,EAAE,EAAE;CACZ,CAAA;AAED,MAAM,UAAU,uBAAuB,CAAC,OAAgB,EAAE,EAAW;IACnE,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,WAAW,CAAC,8BAA8B,OAAO,OAAO,EAAE,EAAE,CAAC,CAAA;IACzE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAgB;IACxC,OAAO,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,OAAO,CAAA;AAChD,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { DomainError, assertRealizationTransition, assertSpecTransition, type BlockerId, type Disposition, type Gate, type ItemCreatedPayload, type ItemId, type ItemKind, type ItemState, type Link, type Realization, type RealizationCause, type SpecStatus, } from './item.js';
2
+ export { assertManualResolve, type BlockerKind, type BlockerOpenedPayload, type BlockerState, type ResolutionRule, } from './blocker.js';
3
+ export { assertOutcomeTransition, isSettled, type DecisionCreatedPayload, type DecisionKind, type DecisionState, type Dossier, type Option, type Outcome, type QAEntry, } from './decision.js';
4
+ export { type AcceptanceStatus, type CriterionState, type CriterionStatus, type EvidenceKind, type EvidenceState, type RunResult, type TestRun, type Waiver, } from './acceptance.js';
5
+ export { WSJF_SCHEME_VERSION, wsjfScore, type PriorityAssessment, type SchemeId, type WsjfInputs, } from './priority.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/model/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,2BAA2B,EAC3B,oBAAoB,EACpB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,IAAI,EACT,KAAK,kBAAkB,EACvB,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,IAAI,EACT,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,UAAU,GAChB,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,mBAAmB,EACnB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,cAAc,GACpB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,uBAAuB,EACvB,SAAS,EACT,KAAK,sBAAsB,EAC3B,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,OAAO,EACZ,KAAK,MAAM,EACX,KAAK,OAAO,EACZ,KAAK,OAAO,GACb,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,OAAO,EACZ,KAAK,MAAM,GACZ,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,KAAK,kBAAkB,EACvB,KAAK,QAAQ,EACb,KAAK,UAAU,GAChB,MAAM,eAAe,CAAA"}
@@ -0,0 +1,7 @@
1
+ // Domain model: Item, Decision, Blocker, AcceptanceCriterion, PriorityAssessment (SPEC §2).
2
+ export { DomainError, assertRealizationTransition, assertSpecTransition, } from './item.js';
3
+ export { assertManualResolve, } from './blocker.js';
4
+ export { assertOutcomeTransition, isSettled, } from './decision.js';
5
+ export {} from './acceptance.js';
6
+ export { WSJF_SCHEME_VERSION, wsjfScore, } from './priority.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/model/index.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,OAAO,EACL,WAAW,EACX,2BAA2B,EAC3B,oBAAoB,GAYrB,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,mBAAmB,GAKpB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,uBAAuB,EACvB,SAAS,GAQV,MAAM,eAAe,CAAA;AACtB,OAAO,EASN,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,mBAAmB,EACnB,SAAS,GAIV,MAAM,eAAe,CAAA"}
@@ -0,0 +1,51 @@
1
+ import type { Ulid } from '../events/types.js';
2
+ import type { PriorityAssessment } from './priority.js';
3
+ export type ItemId = Ulid;
4
+ export type BlockerId = Ulid;
5
+ export type ItemKind = 'feature' | 'bug' | 'chore' | 'decision';
6
+ export type SpecStatus = 'to-specify' | 'specified';
7
+ export type Realization = 'to-do' | 'in-progress' | 'done' | 'cancelled' | 'rejected';
8
+ export type Gate = 'orientation' | 'commitment';
9
+ export type Disposition = 'required' | 'skipped' | 'not-applicable' | 'completed';
10
+ export interface Link {
11
+ kind: string;
12
+ locator: string;
13
+ }
14
+ /** A realization → `rejected` is the consequence of a `no-go` Decision (SPEC §2.3, §2.6). */
15
+ export interface RealizationCause {
16
+ decisionId: ItemId;
17
+ }
18
+ export interface ItemState {
19
+ id: ItemId;
20
+ kind: ItemKind;
21
+ title: string;
22
+ workspace: string;
23
+ specStatus: SpecStatus | 'n/a';
24
+ realization: Realization;
25
+ disposition: Record<Gate, Disposition>;
26
+ priority?: PriorityAssessment;
27
+ parentId?: ItemId;
28
+ sourceKey?: string;
29
+ body?: string;
30
+ links?: Link[];
31
+ }
32
+ export interface ItemCreatedPayload {
33
+ kind: ItemKind;
34
+ title: string;
35
+ workspace: string;
36
+ parentId?: ItemId;
37
+ sourceKey?: string;
38
+ body?: string;
39
+ links?: Link[];
40
+ }
41
+ /** A rejected domain command (illegal transition, unknown aggregate, …). */
42
+ export declare class DomainError extends Error {
43
+ name: string;
44
+ }
45
+ export declare function assertSpecTransition(item: ItemState, to: SpecStatus): void;
46
+ export declare function assertRealizationTransition(item: {
47
+ id: ItemId;
48
+ realization: Realization;
49
+ }, // ItemState or DecisionState — both have realization
50
+ to: Realization, hasCause: boolean): void;
51
+ //# sourceMappingURL=item.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"item.d.ts","sourceRoot":"","sources":["../../src/model/item.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAEvD,MAAM,MAAM,MAAM,GAAG,IAAI,CAAA;AACzB,MAAM,MAAM,SAAS,GAAG,IAAI,CAAA;AAE5B,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,KAAK,GAAG,OAAO,GAAG,UAAU,CAAA;AAC/D,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,WAAW,CAAA;AACnD,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,aAAa,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,CAAA;AAGrF,MAAM,MAAM,IAAI,GAAG,aAAa,GAAG,YAAY,CAAA;AAC/C,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,gBAAgB,GAAG,WAAW,CAAA;AAEjF,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,6FAA6F;AAC7F,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,QAAQ,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,UAAU,GAAG,KAAK,CAAA;IAC9B,WAAW,EAAE,WAAW,CAAA;IACxB,WAAW,EAAE,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;IACtC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;CACf;AAED,4EAA4E;AAC5E,qBAAa,WAAY,SAAQ,KAAK;IAC3B,IAAI,SAAgB;CAC9B;AAkBD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,GAAG,IAAI,CAO1E;AAED,wBAAgB,2BAA2B,CACzC,IAAI,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,EAAE,qDAAqD;AACrG,EAAE,EAAE,WAAW,EACf,QAAQ,EAAE,OAAO,GAChB,IAAI,CAiBN"}
@@ -0,0 +1,42 @@
1
+ /** A rejected domain command (illegal transition, unknown aggregate, …). */
2
+ export class DomainError extends Error {
3
+ name = 'DomainError';
4
+ }
5
+ // Spec axis is monotone: `to-specify → specified` once; reverse rejected (SPEC §2.2).
6
+ const SPEC_TRANSITIONS = {
7
+ 'to-specify': ['specified'],
8
+ specified: [],
9
+ };
10
+ // Realization forward transitions (SPEC §2.3). `rejected` is handled separately — it is only
11
+ // reachable from a `no-go` Decision (with a cause), never a manual transition.
12
+ const REALIZATION_TRANSITIONS = {
13
+ 'to-do': ['in-progress', 'cancelled'],
14
+ 'in-progress': ['done', 'cancelled'],
15
+ done: [],
16
+ cancelled: [],
17
+ rejected: [],
18
+ };
19
+ export function assertSpecTransition(item, to) {
20
+ if (item.specStatus === 'n/a') {
21
+ throw new DomainError(`spec axis is n/a for ${item.kind} item ${item.id}`);
22
+ }
23
+ if (!SPEC_TRANSITIONS[item.specStatus].includes(to)) {
24
+ throw new DomainError(`illegal spec transition ${item.specStatus} -> ${to} (item ${item.id})`);
25
+ }
26
+ }
27
+ export function assertRealizationTransition(item, // ItemState or DecisionState — both have realization
28
+ to, hasCause) {
29
+ if (to === 'rejected') {
30
+ if (!hasCause) {
31
+ throw new DomainError(`realization -> rejected requires a decision cause (item ${item.id})`);
32
+ }
33
+ if (item.realization !== 'to-do' && item.realization !== 'in-progress') {
34
+ throw new DomainError(`illegal realization transition ${item.realization} -> rejected (item ${item.id})`);
35
+ }
36
+ return;
37
+ }
38
+ if (!REALIZATION_TRANSITIONS[item.realization].includes(to)) {
39
+ throw new DomainError(`illegal realization transition ${item.realization} -> ${to} (item ${item.id})`);
40
+ }
41
+ }
42
+ //# sourceMappingURL=item.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"item.js","sourceRoot":"","sources":["../../src/model/item.ts"],"names":[],"mappings":"AAiDA,4EAA4E;AAC5E,MAAM,OAAO,WAAY,SAAQ,KAAK;IAC3B,IAAI,GAAG,aAAa,CAAA;CAC9B;AAED,sFAAsF;AACtF,MAAM,gBAAgB,GAAkD;IACtE,YAAY,EAAE,CAAC,WAAW,CAAC;IAC3B,SAAS,EAAE,EAAE;CACd,CAAA;AAED,6FAA6F;AAC7F,+EAA+E;AAC/E,MAAM,uBAAuB,GAAoD;IAC/E,OAAO,EAAE,CAAC,aAAa,EAAE,WAAW,CAAC;IACrC,aAAa,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC;IACpC,IAAI,EAAE,EAAE;IACR,SAAS,EAAE,EAAE;IACb,QAAQ,EAAE,EAAE;CACb,CAAA;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAe,EAAE,EAAc;IAClE,IAAI,IAAI,CAAC,UAAU,KAAK,KAAK,EAAE,CAAC;QAC9B,MAAM,IAAI,WAAW,CAAC,wBAAwB,IAAI,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;IAC5E,CAAC;IACD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,WAAW,CAAC,2BAA2B,IAAI,CAAC,UAAU,OAAO,EAAE,UAAU,IAAI,CAAC,EAAE,GAAG,CAAC,CAAA;IAChG,CAAC;AACH,CAAC;AAED,MAAM,UAAU,2BAA2B,CACzC,IAA8C,EAAE,qDAAqD;AACrG,EAAe,EACf,QAAiB;IAEjB,IAAI,EAAE,KAAK,UAAU,EAAE,CAAC;QACtB,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,WAAW,CAAC,2DAA2D,IAAI,CAAC,EAAE,GAAG,CAAC,CAAA;QAC9F,CAAC;QACD,IAAI,IAAI,CAAC,WAAW,KAAK,OAAO,IAAI,IAAI,CAAC,WAAW,KAAK,aAAa,EAAE,CAAC;YACvE,MAAM,IAAI,WAAW,CACnB,kCAAkC,IAAI,CAAC,WAAW,sBAAsB,IAAI,CAAC,EAAE,GAAG,CACnF,CAAA;QACH,CAAC;QACD,OAAM;IACR,CAAC;IACD,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,WAAW,CACnB,kCAAkC,IAAI,CAAC,WAAW,OAAO,EAAE,UAAU,IAAI,CAAC,EAAE,GAAG,CAChF,CAAA;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { type ItemId } from './item.js';
2
+ export type SchemeId = 'wsjf';
3
+ /** A versioned, append-only priority assessment (SPEC §2.8). Item.priority = the latest one. */
4
+ export interface PriorityAssessment {
5
+ itemId: ItemId;
6
+ schemeId: SchemeId;
7
+ schemeVersion: number;
8
+ inputs: Record<string, number>;
9
+ score: number;
10
+ order?: number;
11
+ at: string;
12
+ }
13
+ export interface WsjfInputs {
14
+ userBusinessValue: number;
15
+ timeCriticality: number;
16
+ riskReductionOpportunityEnablement: number;
17
+ jobSize: number;
18
+ }
19
+ export declare const WSJF_SCHEME_VERSION = 1;
20
+ /** WSJF (SPEC §2.8): (UBV + TC + RR/OE) / jobSize. Never hardcoded; used only when active. */
21
+ export declare function wsjfScore(inputs: WsjfInputs): number;
22
+ //# sourceMappingURL=priority.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"priority.d.ts","sourceRoot":"","sources":["../../src/model/priority.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,MAAM,EAAE,MAAM,WAAW,CAAA;AAEpD,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAA;AAE7B,gGAAgG;AAChG,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,QAAQ,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,EAAE,EAAE,MAAM,CAAA;CACX;AAED,MAAM,WAAW,UAAU;IACzB,iBAAiB,EAAE,MAAM,CAAA;IACzB,eAAe,EAAE,MAAM,CAAA;IACvB,kCAAkC,EAAE,MAAM,CAAA;IAC1C,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,eAAO,MAAM,mBAAmB,IAAI,CAAA;AAEpC,8FAA8F;AAC9F,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAUpD"}
@@ -0,0 +1,13 @@
1
+ import { DomainError } from './item.js';
2
+ export const WSJF_SCHEME_VERSION = 1;
3
+ /** WSJF (SPEC §2.8): (UBV + TC + RR/OE) / jobSize. Never hardcoded; used only when active. */
4
+ export function wsjfScore(inputs) {
5
+ if (!(inputs.jobSize > 0)) {
6
+ throw new DomainError('WSJF jobSize must be > 0');
7
+ }
8
+ return ((inputs.userBusinessValue +
9
+ inputs.timeCriticality +
10
+ inputs.riskReductionOpportunityEnablement) /
11
+ inputs.jobSize);
12
+ }
13
+ //# sourceMappingURL=priority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"priority.js","sourceRoot":"","sources":["../../src/model/priority.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAe,MAAM,WAAW,CAAA;AAsBpD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAA;AAEpC,8FAA8F;AAC9F,MAAM,UAAU,SAAS,CAAC,MAAkB;IAC1C,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,WAAW,CAAC,0BAA0B,CAAC,CAAA;IACnD,CAAC;IACD,OAAO,CACL,CAAC,MAAM,CAAC,iBAAiB;QACvB,MAAM,CAAC,eAAe;QACtB,MAAM,CAAC,kCAAkC,CAAC;QAC5C,MAAM,CAAC,OAAO,CACf,CAAA;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/priority/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAA"}
@@ -0,0 +1,4 @@
1
+ // Prioritization: PriorityAssessment (versioned, append-only), WSJF scheme (SPEC §2.8).
2
+ // Implemented in Lot 4b.
3
+ export {};
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/priority/index.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,yBAAyB;AACzB,OAAO,EAAE,CAAA"}
@@ -0,0 +1,18 @@
1
+ import type { ItemState } from '../model/item.js';
2
+ import { type State } from '../state/fold.js';
3
+ export type Bucket = 'AWAITED' | 'DROPPED' | 'DONE' | 'TO-DO';
4
+ export declare const BUCKETS: readonly Bucket[];
5
+ export interface ReportConfig {
6
+ /** The "current" commit for staleness (SPEC §2.4); CLI default = repo git HEAD. */
7
+ baselineCommit: string;
8
+ /** When true, a `done` item only counts as DONE if acceptanceStatus=pass (SPEC §7.3, default false). */
9
+ requireAccepted: boolean;
10
+ }
11
+ /**
12
+ * Place a non-decision item in a bucket — SPEC §7, first match wins:
13
+ * AWAITED (any open blocker) > DROPPED (cancelled/rejected) > DONE (done, and accepted if
14
+ * required) > TO-DO. A `done` item with an open blocker is AWAITED (precedence), and a `done`
15
+ * item that is not yet accepted (under requireAccepted) falls through to TO-DO.
16
+ */
17
+ export declare function bucketOf(state: State, item: ItemState, config: ReportConfig): Bucket;
18
+ //# sourceMappingURL=buckets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buckets.d.ts","sourceRoot":"","sources":["../../src/report/buckets.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAuB,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAElE,MAAM,MAAM,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAA;AAC7D,eAAO,MAAM,OAAO,EAAE,SAAS,MAAM,EAA4C,CAAA;AAEjF,MAAM,WAAW,YAAY;IAC3B,mFAAmF;IACnF,cAAc,EAAE,MAAM,CAAA;IACtB,wGAAwG;IACxG,eAAe,EAAE,OAAO,CAAA;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAapF"}
@@ -0,0 +1,24 @@
1
+ import { acceptanceStatus } from '../accept/status.js';
2
+ import { openBlockersForItem } from '../state/fold.js';
3
+ export const BUCKETS = ['AWAITED', 'DROPPED', 'DONE', 'TO-DO'];
4
+ /**
5
+ * Place a non-decision item in a bucket — SPEC §7, first match wins:
6
+ * AWAITED (any open blocker) > DROPPED (cancelled/rejected) > DONE (done, and accepted if
7
+ * required) > TO-DO. A `done` item with an open blocker is AWAITED (precedence), and a `done`
8
+ * item that is not yet accepted (under requireAccepted) falls through to TO-DO.
9
+ */
10
+ export function bucketOf(state, item, config) {
11
+ if (openBlockersForItem(state, item.id).length > 0)
12
+ return 'AWAITED';
13
+ if (item.realization === 'cancelled' || item.realization === 'rejected')
14
+ return 'DROPPED';
15
+ if (item.realization === 'done') {
16
+ if (config.requireAccepted &&
17
+ acceptanceStatus(state, item.id, config.baselineCommit) !== 'pass') {
18
+ return 'TO-DO';
19
+ }
20
+ return 'DONE';
21
+ }
22
+ return 'TO-DO';
23
+ }
24
+ //# sourceMappingURL=buckets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buckets.js","sourceRoot":"","sources":["../../src/report/buckets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAEtD,OAAO,EAAE,mBAAmB,EAAc,MAAM,kBAAkB,CAAA;AAGlE,MAAM,CAAC,MAAM,OAAO,GAAsB,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;AASjF;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAY,EAAE,IAAe,EAAE,MAAoB;IAC1E,IAAI,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,SAAS,CAAA;IACpE,IAAI,IAAI,CAAC,WAAW,KAAK,WAAW,IAAI,IAAI,CAAC,WAAW,KAAK,UAAU;QAAE,OAAO,SAAS,CAAA;IACzF,IAAI,IAAI,CAAC,WAAW,KAAK,MAAM,EAAE,CAAC;QAChC,IACE,MAAM,CAAC,eAAe;YACtB,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,cAAc,CAAC,KAAK,MAAM,EAClE,CAAC;YACD,OAAO,OAAO,CAAA;QAChB,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC"}
@@ -0,0 +1,44 @@
1
+ import type { AcceptanceStatus } from '../model/acceptance.js';
2
+ import type { DecisionKind, Outcome } from '../model/decision.js';
3
+ import type { ItemId, ItemKind, Realization } from '../model/item.js';
4
+ import type { State } from '../state/fold.js';
5
+ import { type Bucket } from './buckets.js';
6
+ export interface ReportRow {
7
+ id: ItemId;
8
+ title: string;
9
+ kind: ItemKind;
10
+ workspace: string;
11
+ bucket: Bucket;
12
+ realization: Realization;
13
+ acceptance: AcceptanceStatus;
14
+ priority?: number;
15
+ }
16
+ export interface DecisionRow {
17
+ id: ItemId;
18
+ title: string;
19
+ workspace: string;
20
+ decisionKind: DecisionKind;
21
+ realization: Realization;
22
+ outcome: Outcome;
23
+ }
24
+ export interface Report {
25
+ buckets: Record<Bucket, ReportRow[]>;
26
+ decisions?: DecisionRow[];
27
+ }
28
+ export interface ReportOptions {
29
+ baselineCommit: string;
30
+ requireAccepted?: boolean;
31
+ decisions?: boolean;
32
+ }
33
+ /** Build the bucketed report over non-decision items (SPEC §7). `decisions:true` adds the decision view. */
34
+ export declare function buildReport(state: State, options: ReportOptions): Report;
35
+ export interface QueryFilter {
36
+ kind?: Exclude<ItemKind, 'decision'>;
37
+ workspace?: string;
38
+ bucket?: Bucket;
39
+ realization?: Realization;
40
+ acceptance?: AcceptanceStatus;
41
+ }
42
+ /** Flat, filtered view over the report rows (SPEC §6 `query`). */
43
+ export declare function query(state: State, filter: QueryFilter, options: ReportOptions): ReportRow[];
44
+ //# sourceMappingURL=build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/report/build.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAa,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAChF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAqB,KAAK,MAAM,EAAqB,MAAM,cAAc,CAAA;AAEhF,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,QAAQ,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,WAAW,CAAA;IACxB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,YAAY,CAAA;IAC1B,WAAW,EAAE,WAAW,CAAA;IACxB,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;IACpC,SAAS,CAAC,EAAE,WAAW,EAAE,CAAA;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAyBD,4GAA4G;AAC5G,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAwBxE;AAED,MAAM,WAAW,WAAW;IAG1B,IAAI,CAAC,EAAE,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;IACpC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,UAAU,CAAC,EAAE,gBAAgB,CAAA;CAC9B;AAED,kEAAkE;AAClE,wBAAgB,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,GAAG,SAAS,EAAE,CAW5F"}
@@ -0,0 +1,62 @@
1
+ import { acceptanceStatus } from '../accept/status.js';
2
+ import { BUCKETS, bucketOf } from './buckets.js';
3
+ function toRow(state, item, config) {
4
+ return {
5
+ id: item.id,
6
+ title: item.title,
7
+ kind: item.kind,
8
+ workspace: item.workspace,
9
+ bucket: bucketOf(state, item, config),
10
+ realization: item.realization,
11
+ acceptance: acceptanceStatus(state, item.id, config.baselineCommit),
12
+ ...(item.priority !== undefined ? { priority: item.priority.score } : {}),
13
+ };
14
+ }
15
+ // Active prioritization scheme: higher score first; un-prioritized items after; stable by id.
16
+ function byPriority(a, b) {
17
+ if (a.priority !== undefined && b.priority !== undefined) {
18
+ return b.priority - a.priority || a.id.localeCompare(b.id);
19
+ }
20
+ if (a.priority !== undefined)
21
+ return -1;
22
+ if (b.priority !== undefined)
23
+ return 1;
24
+ return a.id.localeCompare(b.id);
25
+ }
26
+ /** Build the bucketed report over non-decision items (SPEC §7). `decisions:true` adds the decision view. */
27
+ export function buildReport(state, options) {
28
+ const config = {
29
+ baselineCommit: options.baselineCommit,
30
+ requireAccepted: options.requireAccepted ?? false,
31
+ };
32
+ const buckets = { AWAITED: [], DROPPED: [], DONE: [], 'TO-DO': [] };
33
+ for (const item of state.items.values()) {
34
+ const row = toRow(state, item, config);
35
+ buckets[row.bucket].push(row);
36
+ }
37
+ for (const bucket of BUCKETS)
38
+ buckets[bucket].sort(byPriority);
39
+ const report = { buckets };
40
+ if (options.decisions) {
41
+ report.decisions = [...state.decisions.values()].map((d) => ({
42
+ id: d.id,
43
+ title: d.title,
44
+ workspace: d.workspace,
45
+ decisionKind: d.decisionKind,
46
+ realization: d.realization,
47
+ outcome: d.outcome,
48
+ }));
49
+ }
50
+ return report;
51
+ }
52
+ /** Flat, filtered view over the report rows (SPEC §6 `query`). */
53
+ export function query(state, filter, options) {
54
+ const report = buildReport(state, options);
55
+ const rows = BUCKETS.flatMap((bucket) => report.buckets[bucket]);
56
+ return rows.filter((r) => (filter.kind === undefined || r.kind === filter.kind) &&
57
+ (filter.workspace === undefined || r.workspace === filter.workspace) &&
58
+ (filter.bucket === undefined || r.bucket === filter.bucket) &&
59
+ (filter.realization === undefined || r.realization === filter.realization) &&
60
+ (filter.acceptance === undefined || r.acceptance === filter.acceptance));
61
+ }
62
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/report/build.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { Report, ReportRow } from './build.js';
2
+ export type Format = 'json' | 'text' | 'md';
3
+ export declare function formatReport(report: Report, format: Format): string;
4
+ export declare function formatRows(rows: ReportRow[], format: Format): string;
5
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/report/format.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAEnD,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;AAoD3C,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAqBnE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAYpE"}