@boxxy/model 0.1.1 → 0.1.3
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/README.md +8 -6
- package/dist/closeouts/build-close-out-schema.d.ts +31 -0
- package/dist/closeouts/close-out-answer-schema.d.ts +3 -0
- package/dist/closeouts/close-out-schema.d.ts +3 -0
- package/dist/closeouts/design-close-out-schema.d.ts +30 -0
- package/dist/closeouts/friction-schema.d.ts +14 -0
- package/dist/closeouts/open-item-schema.d.ts +3 -0
- package/dist/closeouts/review-close-out-schema.d.ts +40 -0
- package/dist/closeouts/triage-close-out-schema.d.ts +40 -0
- package/dist/closeouts/types.d.ts +221 -0
- package/dist/dispatch/build-applied-change.d.ts +6 -0
- package/dist/dispatch/collect-seat-sync.d.ts +14 -0
- package/dist/dispatch/pick-seat-take.d.ts +10 -0
- package/dist/dispatch/types.d.ts +11 -0
- package/dist/facts/outbox-fact-schema.d.ts +3 -0
- package/dist/facts/parse-new-fact.d.ts +2 -0
- package/dist/facts/types.d.ts +191 -0
- package/dist/facts/work-fact-schemas.d.ts +293 -0
- package/dist/index.d.ts +64 -16
- package/dist/items/build-item-views.d.ts +4 -0
- package/dist/items/collect-retries.d.ts +3 -0
- package/dist/items/collect-settled.d.ts +3 -0
- package/dist/items/derive-item-state.d.ts +17 -0
- package/dist/{live-levers.d.ts → items/live-levers.d.ts} +1 -1
- package/dist/items/types.d.ts +12 -0
- package/dist/pipeline/advance.d.ts +10 -0
- package/dist/pipeline/constants.d.ts +2 -0
- package/dist/pipeline/count-trailing.d.ts +1 -0
- package/dist/pipeline/find-position.d.ts +9 -0
- package/dist/pipeline/find-step.d.ts +3 -0
- package/dist/pipeline/merge-by-time.d.ts +9 -0
- package/dist/pipeline/position-schema.d.ts +3 -0
- package/dist/pipeline/types.d.ts +28 -0
- package/dist/planning/define-admission.d.ts +3 -0
- package/dist/planning/define-gate.d.ts +3 -0
- package/dist/planning/define-signal.d.ts +3 -0
- package/dist/planning/is-filter-match.d.ts +3 -0
- package/dist/planning/limit-fill-schema.d.ts +3 -0
- package/dist/{signal-key.d.ts → planning/signal-key.d.ts} +1 -1
- package/dist/planning/types.d.ts +155 -0
- package/dist/ports/types.d.ts +289 -0
- package/dist/reports/constants.d.ts +3 -0
- package/dist/reports/cost-to-land-schema.d.ts +29 -0
- package/dist/reports/outbox-status.d.ts +16 -0
- package/dist/reports/stage-time-schema.d.ts +25 -0
- package/dist/reports/types.d.ts +5 -0
- package/dist/rows/actor-ref-schema.d.ts +2 -0
- package/dist/rows/attempt-row-schema.d.ts +3 -0
- package/dist/rows/attempt-session-row-schema.d.ts +3 -0
- package/dist/{brand-schemas.d.ts → rows/brand-schemas.d.ts} +5 -2
- package/dist/rows/caller-identity-schema.d.ts +3 -0
- package/dist/rows/criterion-schema.d.ts +3 -0
- package/dist/rows/decision-row-schema.d.ts +34 -0
- package/dist/rows/evidence-row-schema.d.ts +3 -0
- package/dist/rows/item-row-schema.d.ts +28 -0
- package/dist/rows/item-view-schema.d.ts +3 -0
- package/dist/rows/lease-row-schema.d.ts +3 -0
- package/dist/rows/lever-row-schema.d.ts +12 -0
- package/dist/rows/limit-schema.d.ts +3 -0
- package/dist/rows/limit-seat-row-schema.d.ts +3 -0
- package/dist/rows/note-row-schema.d.ts +3 -0
- package/dist/rows/notice-row-schema.d.ts +3 -0
- package/dist/rows/pull-request-row-schema.d.ts +3 -0
- package/dist/rows/relation-row-schema.d.ts +3 -0
- package/dist/rows/row-schemas.d.ts +5 -0
- package/dist/rows/runner-row-schema.d.ts +3 -0
- package/dist/rows/spawn-request-schema.d.ts +3 -0
- package/dist/rules/define-phase.d.ts +3 -0
- package/dist/rules/load-rejection-schema.d.ts +3 -0
- package/dist/rules/types.d.ts +244 -0
- package/dist/test-utils/build-mock-cost-to-land.d.ts +2 -0
- package/dist/test-utils/build-mock-evidence-row.d.ts +2 -0
- package/dist/test-utils/build-mock-fact-id.d.ts +2 -0
- package/dist/test-utils/build-mock-frame-item.d.ts +2 -0
- package/dist/test-utils/build-mock-frame.d.ts +2 -0
- package/dist/test-utils/build-mock-item-rules.d.ts +2 -0
- package/dist/test-utils/build-mock-lease-row.d.ts +1 -1
- package/dist/test-utils/build-mock-outbox-fact.d.ts +2 -0
- package/dist/test-utils/build-mock-phase-kind.d.ts +7 -0
- package/dist/test-utils/build-mock-pipeline.d.ts +7 -0
- package/dist/test-utils/build-mock-relation-row.d.ts +2 -0
- package/dist/test-utils/build-mock-settled.d.ts +9 -0
- package/dist/test-utils/build-mock-snapshot.d.ts +2 -0
- package/dist/test-utils/build-mock-v1-attempt-row.d.ts +2 -0
- package/dist/test-utils/build-mock-v1-item-row.d.ts +2 -0
- package/dist/test-utils/build-mock-v1-item-view.d.ts +2 -0
- package/dist/test-utils/build-mock-v1-lever-row.d.ts +2 -0
- package/dist/test-utils/build-mock-v1-pull-request-row.d.ts +2 -0
- package/dist/test-utils/build-mock-work-fact.d.ts +12 -0
- package/dist/test-utils/create-fake-notifier.d.ts +9 -0
- package/dist/test-utils/create-fake-pepys-reader.d.ts +13 -0
- package/dist/test-utils/fact-sink-contract.d.ts +14 -0
- package/dist/test-utils/pepys-reader-contract.d.ts +17 -0
- package/dist/{types/core.d.ts → types.d.ts} +94 -36
- package/dist/utils/format-key-path.d.ts +1 -0
- package/dist/utils/to-json-value.d.ts +2 -0
- package/package.json +14 -3
- package/src/{build-close-out-schema.ts → closeouts/build-close-out-schema.ts} +5 -10
- package/src/closeouts/close-out-answer-schema.ts +42 -0
- package/src/closeouts/close-out-schema.ts +13 -0
- package/src/closeouts/design-close-out-schema.ts +20 -0
- package/src/closeouts/friction-schema.ts +11 -0
- package/src/closeouts/open-item-schema.ts +8 -0
- package/src/closeouts/review-close-out-schema.ts +38 -0
- package/src/closeouts/triage-close-out-schema.ts +29 -0
- package/src/closeouts/types.ts +230 -0
- package/src/dispatch/build-applied-change.ts +57 -0
- package/src/dispatch/collect-seat-sync.ts +86 -0
- package/src/dispatch/pick-seat-take.ts +39 -0
- package/src/dispatch/types.ts +14 -0
- package/src/facts/outbox-fact-schema.ts +22 -0
- package/src/facts/parse-new-fact.ts +16 -0
- package/src/facts/types.ts +235 -0
- package/src/facts/work-fact-schemas.ts +201 -0
- package/src/index.ts +147 -41
- package/src/items/build-item-views.ts +146 -0
- package/src/items/collect-retries.ts +12 -0
- package/src/items/collect-settled.ts +20 -0
- package/src/items/derive-item-state.ts +95 -0
- package/src/{live-levers.ts → items/live-levers.ts} +1 -1
- package/src/items/types.ts +26 -0
- package/src/pipeline/advance.ts +78 -0
- package/src/pipeline/constants.ts +12 -0
- package/src/pipeline/count-trailing.ts +16 -0
- package/src/pipeline/find-position.ts +74 -0
- package/src/pipeline/find-step.ts +6 -0
- package/src/pipeline/merge-by-time.ts +33 -0
- package/src/pipeline/position-schema.ts +27 -0
- package/src/pipeline/types.ts +47 -0
- package/src/{define-admission.ts → planning/define-admission.ts} +2 -2
- package/src/{define-gate.ts → planning/define-gate.ts} +2 -2
- package/src/{define-signal.ts → planning/define-signal.ts} +2 -2
- package/src/planning/is-filter-match.ts +10 -0
- package/src/planning/limit-fill-schema.ts +12 -0
- package/src/{signal-key.ts → planning/signal-key.ts} +1 -1
- package/src/planning/types.ts +216 -0
- package/src/ports/types.ts +412 -0
- package/src/reports/constants.ts +6 -0
- package/src/reports/cost-to-land-schema.ts +47 -0
- package/src/reports/outbox-status.ts +22 -0
- package/src/reports/stage-time-schema.ts +21 -0
- package/src/reports/types.ts +7 -0
- package/src/rows/actor-ref-schema.ts +17 -0
- package/src/rows/attempt-row-schema.ts +69 -0
- package/src/rows/attempt-session-row-schema.ts +12 -0
- package/src/{brand-schemas.ts → rows/brand-schemas.ts} +5 -2
- package/src/rows/caller-identity-schema.ts +7 -0
- package/src/rows/criterion-schema.ts +9 -0
- package/src/rows/decision-row-schema.ts +34 -0
- package/src/rows/evidence-row-schema.ts +13 -0
- package/src/rows/item-row-schema.ts +32 -0
- package/src/rows/item-view-schema.ts +31 -0
- package/src/rows/lease-row-schema.ts +12 -0
- package/src/rows/lever-row-schema.ts +17 -0
- package/src/rows/limit-schema.ts +12 -0
- package/src/rows/limit-seat-row-schema.ts +12 -0
- package/src/rows/note-row-schema.ts +12 -0
- package/src/rows/notice-row-schema.ts +17 -0
- package/src/rows/pull-request-row-schema.ts +15 -0
- package/src/rows/relation-row-schema.ts +13 -0
- package/src/rows/row-schemas.ts +30 -0
- package/src/rows/runner-row-schema.ts +9 -0
- package/src/rows/spawn-request-schema.ts +15 -0
- package/src/rules/define-phase.ts +12 -0
- package/src/rules/load-rejection-schema.ts +51 -0
- package/src/rules/types.ts +291 -0
- package/src/test-utils/build-mock-cost-to-land.ts +31 -0
- package/src/test-utils/build-mock-evidence-row.ts +17 -0
- package/src/test-utils/build-mock-fact-id.ts +7 -0
- package/src/test-utils/build-mock-frame-item.ts +14 -0
- package/src/test-utils/build-mock-frame.ts +13 -0
- package/src/test-utils/build-mock-item-rules.ts +17 -0
- package/src/test-utils/build-mock-lease-row.ts +2 -2
- package/src/test-utils/build-mock-outbox-fact.ts +22 -0
- package/src/test-utils/build-mock-phase-kind.ts +29 -0
- package/src/test-utils/build-mock-pipeline.ts +52 -0
- package/src/test-utils/{build-mock-link-row.ts → build-mock-relation-row.ts} +4 -4
- package/src/test-utils/build-mock-settled.ts +18 -0
- package/src/test-utils/build-mock-snapshot.ts +13 -0
- package/src/test-utils/{build-mock-attempt-row.ts → build-mock-v1-attempt-row.ts} +28 -9
- package/src/test-utils/{build-mock-item-row.ts → build-mock-v1-item-row.ts} +7 -3
- package/src/test-utils/build-mock-v1-item-view.ts +29 -0
- package/src/test-utils/{build-mock-lever-row.ts → build-mock-v1-lever-row.ts} +5 -3
- package/src/test-utils/build-mock-v1-pull-request-row.ts +26 -0
- package/src/test-utils/build-mock-work-fact.ts +179 -0
- package/src/test-utils/create-fake-notifier.ts +54 -0
- package/src/test-utils/create-fake-pepys-reader.ts +73 -0
- package/src/test-utils/fact-sink-contract.ts +103 -0
- package/src/test-utils/pepys-reader-contract.ts +117 -0
- package/src/{types/core.ts → types.ts} +184 -48
- package/src/utils/format-key-path.ts +19 -0
- package/src/utils/to-json-value.ts +25 -0
- package/dist/build-close-out-schema.d.ts +0 -3
- package/dist/define-admission.d.ts +0 -3
- package/dist/define-gate.d.ts +0 -3
- package/dist/define-signal.d.ts +0 -3
- package/dist/derive-item-state.d.ts +0 -2
- package/dist/fact-schemas.d.ts +0 -5
- package/dist/friction-schema.d.ts +0 -3
- package/dist/test-utils/build-mock-attempt-row.d.ts +0 -2
- package/dist/test-utils/build-mock-item-row.d.ts +0 -2
- package/dist/test-utils/build-mock-item-rows.d.ts +0 -2
- package/dist/test-utils/build-mock-lever-row.d.ts +0 -2
- package/dist/test-utils/build-mock-link-row.d.ts +0 -2
- package/dist/test-utils/build-mock-pull-request-row.d.ts +0 -2
- package/dist/types/dispatch.d.ts +0 -82
- package/dist/types/facts.d.ts +0 -154
- package/dist/types/planning.d.ts +0 -94
- package/dist/types/ports.d.ts +0 -218
- package/dist/types/registries.d.ts +0 -150
- package/src/derive-item-state.ts +0 -76
- package/src/fact-schemas.ts +0 -138
- package/src/friction-schema.ts +0 -10
- package/src/test-utils/build-mock-item-rows.ts +0 -14
- package/src/test-utils/build-mock-pull-request-row.ts +0 -16
- package/src/types/dispatch.ts +0 -95
- package/src/types/facts.ts +0 -166
- package/src/types/planning.ts +0 -136
- package/src/types/ports.ts +0 -262
- package/src/types/registries.ts +0 -185
- /package/dist/test-utils/{seed-faker.d.ts → pin-faker-seed.d.ts} +0 -0
- /package/src/test-utils/{seed-faker.ts → pin-faker-seed.ts} +0 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { ContentHash, JsonValue } from '@boxxy/content-hash';
|
|
2
2
|
import type { z } from 'zod';
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
3
|
+
import type { CloseOut } from './closeouts/types.ts';
|
|
4
|
+
import type { HoldReason, Position } from './pipeline/types.ts';
|
|
5
|
+
import type { brandSchemas } from './rows/brand-schemas.ts';
|
|
5
6
|
type BrandOf<K extends keyof typeof brandSchemas> = z.output<(typeof brandSchemas)[K]>;
|
|
6
7
|
export type Instant = BrandOf<'instant'>;
|
|
7
8
|
export type Minutes = number;
|
|
@@ -20,10 +21,11 @@ export interface PullRequestRef {
|
|
|
20
21
|
readonly number: number;
|
|
21
22
|
}
|
|
22
23
|
export type ItemKindName = BrandOf<'itemKindName'>;
|
|
23
|
-
export type
|
|
24
|
+
export type RelationTypeName = BrandOf<'relationTypeName'>;
|
|
24
25
|
export type PhaseName = BrandOf<'phaseName'>;
|
|
25
26
|
export type PipelineName = BrandOf<'pipelineName'>;
|
|
26
27
|
export type PoolName = BrandOf<'poolName'>;
|
|
28
|
+
export type LimitName = BrandOf<'limitName'>;
|
|
27
29
|
export type RecipeName = BrandOf<'recipeName'>;
|
|
28
30
|
export type WorkerKindName = BrandOf<'workerKindName'>;
|
|
29
31
|
export type SourceName = BrandOf<'sourceName'>;
|
|
@@ -32,6 +34,7 @@ export type LeverKind = `${string}.${string}`;
|
|
|
32
34
|
export type RecipeHash = BrandOf<'recipeHash'>;
|
|
33
35
|
export type SnapshotHash = BrandOf<'snapshotHash'>;
|
|
34
36
|
export type RulesVersion = BrandOf<'rulesVersion'>;
|
|
37
|
+
export type OutcomeName = BrandOf<'outcomeName'>;
|
|
35
38
|
export interface ConceptPin {
|
|
36
39
|
readonly ref: `${string}@${number}`;
|
|
37
40
|
readonly sourceHash: ContentHash;
|
|
@@ -49,12 +52,22 @@ export type Actor = {
|
|
|
49
52
|
readonly attempt: AttemptId;
|
|
50
53
|
};
|
|
51
54
|
export type ActorRef = 'boxxy:owner:local' | `boxxy:runner:${string}` | `boxxy:attempt:${string}` | `boxxy:hook:${string}`;
|
|
52
|
-
export
|
|
55
|
+
export interface CallerIdentity {
|
|
56
|
+
readonly issuer: string;
|
|
57
|
+
readonly subject: string;
|
|
58
|
+
}
|
|
59
|
+
export type EvidenceKind = 'pull_request' | 'commit' | 'test' | 'ci-run' | 'live-check';
|
|
53
60
|
export interface Criterion {
|
|
54
61
|
readonly id: CriterionId;
|
|
55
62
|
readonly text: string;
|
|
56
63
|
readonly evidence: readonly FactId[];
|
|
57
64
|
}
|
|
65
|
+
export type DesignMode = 'agent' | 'attended';
|
|
66
|
+
export type SessionMode = 'agent' | 'attended';
|
|
67
|
+
export type Product = 'claude_code' | 'codex';
|
|
68
|
+
export interface ItemFields {
|
|
69
|
+
readonly designMode?: DesignMode;
|
|
70
|
+
}
|
|
58
71
|
export interface ItemRow {
|
|
59
72
|
readonly id: ItemId;
|
|
60
73
|
readonly kind: ItemKindName;
|
|
@@ -62,14 +75,31 @@ export interface ItemRow {
|
|
|
62
75
|
readonly title: string;
|
|
63
76
|
readonly outcome: string;
|
|
64
77
|
readonly acceptance: readonly Criterion[];
|
|
78
|
+
readonly fields: ItemFields;
|
|
79
|
+
readonly labels: readonly string[];
|
|
65
80
|
readonly foundInAttempt: AttemptId | null;
|
|
66
81
|
readonly filedBy: ActorRef;
|
|
67
82
|
readonly filedAt: Instant;
|
|
68
83
|
readonly closedAt: Instant | null;
|
|
69
84
|
readonly closeReason: string | null;
|
|
85
|
+
readonly keptSession: KeptSession | null;
|
|
86
|
+
}
|
|
87
|
+
export interface KeptSession {
|
|
88
|
+
readonly atcSession: AtcSessionId;
|
|
89
|
+
readonly target: string;
|
|
90
|
+
readonly attempt: AttemptId;
|
|
91
|
+
readonly keptAt: Instant;
|
|
92
|
+
readonly caller: CallerIdentity | null;
|
|
93
|
+
}
|
|
94
|
+
export interface NoteRow {
|
|
95
|
+
readonly item: ItemId;
|
|
96
|
+
readonly seq: number;
|
|
97
|
+
readonly text: string;
|
|
98
|
+
readonly by: ActorRef;
|
|
99
|
+
readonly at: Instant;
|
|
70
100
|
}
|
|
71
101
|
export type ItemState = 'idea' | 'ready' | 'running' | 'blocked' | 'waiting' | 'done' | 'archived';
|
|
72
|
-
export type WaitingReason = '
|
|
102
|
+
export type WaitingReason = 'pull request open' | 'no pull request linked' | 'pull request closed unmerged' | HoldReason;
|
|
73
103
|
export type DerivedState = {
|
|
74
104
|
readonly state: Exclude<ItemState, 'waiting'>;
|
|
75
105
|
} | {
|
|
@@ -78,24 +108,12 @@ export type DerivedState = {
|
|
|
78
108
|
};
|
|
79
109
|
export interface ItemView extends ItemRow {
|
|
80
110
|
readonly derived: DerivedState;
|
|
111
|
+
readonly position: Position;
|
|
81
112
|
}
|
|
82
|
-
export interface
|
|
83
|
-
readonly links: readonly LinkRow[];
|
|
84
|
-
readonly blockerStates: ReadonlyMap<ItemId, ItemState>;
|
|
85
|
-
readonly levers: readonly LeverRow[];
|
|
86
|
-
readonly attempts: readonly AttemptRow[];
|
|
87
|
-
readonly liveLease: LeaseRow | null;
|
|
88
|
-
readonly pullRequests: readonly PullRequestRow[];
|
|
89
|
-
readonly maxAttempts: number;
|
|
90
|
-
}
|
|
91
|
-
export type MaxAttemptsByKind = ReadonlyMap<ItemKindName, ReadonlyMap<PhaseName, number>>;
|
|
92
|
-
export interface ItemWithLevers extends ItemView {
|
|
93
|
-
readonly levers: readonly LeverRow[];
|
|
94
|
-
}
|
|
95
|
-
export interface LinkRow {
|
|
113
|
+
export interface RelationRow {
|
|
96
114
|
readonly source: ItemId;
|
|
97
115
|
readonly target: ItemId;
|
|
98
|
-
readonly type:
|
|
116
|
+
readonly type: RelationTypeName;
|
|
99
117
|
readonly addedBy: ActorRef;
|
|
100
118
|
readonly addedAt: Instant;
|
|
101
119
|
readonly removedAt: Instant | null;
|
|
@@ -107,13 +125,17 @@ export interface LeverRow {
|
|
|
107
125
|
readonly until: Instant | null;
|
|
108
126
|
readonly expiresAt: Instant | null;
|
|
109
127
|
readonly reason: string | null;
|
|
128
|
+
readonly phase: PhaseName | null;
|
|
110
129
|
readonly actor: ActorRef;
|
|
111
130
|
readonly at: Instant;
|
|
112
131
|
}
|
|
113
|
-
export type AttemptState = 'starting' | 'running' | 'reconciling' | 'succeeded' | 'failed';
|
|
114
|
-
export type LiveAttemptState =
|
|
115
|
-
export type
|
|
116
|
-
export type ForcedFailure =
|
|
132
|
+
export type AttemptState = 'starting' | 'running' | 'reconciling' | 'sleeping' | 'waking' | 'closing' | 'succeeded' | 'failed';
|
|
133
|
+
export type LiveAttemptState = Exclude<AttemptState, 'succeeded' | 'failed'>;
|
|
134
|
+
export type ClosingCause = 'closed-out' | 'timed-out' | 'item-closed' | 'stalled' | 'skill-missing' | 'turn-ended' | 'usage-limit';
|
|
135
|
+
export type ForcedFailure = 'spawn-refused' | 'no-capacity' | 'spawn-lost' | 'session-lost' | 'resume-lost' | 'timed-out' | 'item-closed' | 'skill-missing' | 'stalled' | 'usage-limit';
|
|
136
|
+
export type KnownFailure = ForcedFailure | 'closeout-missing' | 'closeout-unsettleable';
|
|
137
|
+
export type EngineOutcome = 'lost' | 'unsettleable';
|
|
138
|
+
export type FieldValues = Readonly<Record<string, readonly string[]>>;
|
|
117
139
|
export interface AttemptRow {
|
|
118
140
|
readonly id: AttemptId;
|
|
119
141
|
readonly item: ItemId;
|
|
@@ -123,23 +145,42 @@ export interface AttemptRow {
|
|
|
123
145
|
readonly recipeHash: RecipeHash;
|
|
124
146
|
readonly rulesVersion: RulesVersion;
|
|
125
147
|
readonly pool: PoolName;
|
|
126
|
-
readonly slot: number;
|
|
127
|
-
readonly slotGen: number;
|
|
128
148
|
readonly leaseGen: number;
|
|
129
149
|
readonly spawnRequest: JsonValue;
|
|
130
150
|
readonly spawnRequestHash: ContentHash;
|
|
131
151
|
readonly state: AttemptState;
|
|
132
152
|
readonly failure: string | null;
|
|
133
153
|
readonly atcSession: AtcSessionId | null;
|
|
134
|
-
readonly
|
|
154
|
+
readonly caller: CallerIdentity | null;
|
|
135
155
|
readonly claimedAt: Instant;
|
|
136
156
|
readonly startedAt: Instant | null;
|
|
137
157
|
readonly endedAt: Instant | null;
|
|
158
|
+
readonly fields: FieldValues;
|
|
159
|
+
readonly mode: SessionMode;
|
|
160
|
+
readonly round: number;
|
|
161
|
+
readonly input: JsonValue;
|
|
162
|
+
readonly holdGen: number;
|
|
163
|
+
readonly closeOut: CloseOut | null;
|
|
164
|
+
readonly closeOutHash: ContentHash | null;
|
|
165
|
+
readonly closeOutFact: FactId | null;
|
|
166
|
+
readonly closing: ClosingCause | null;
|
|
167
|
+
readonly closingAt: Instant | null;
|
|
168
|
+
readonly suspendRequestedAt: Instant | null;
|
|
169
|
+
readonly sleptAt: Instant | null;
|
|
170
|
+
readonly wakeRequestedAt: Instant | null;
|
|
171
|
+
readonly wokenAt: Instant | null;
|
|
172
|
+
readonly outcome: OutcomeName | EngineOutcome | null;
|
|
173
|
+
readonly returnedOutcome: string | null;
|
|
174
|
+
readonly strayedAt: Instant | null;
|
|
175
|
+
readonly sessionStoppedAt: Instant | null;
|
|
176
|
+
readonly sessionForgottenAt: Instant | null;
|
|
138
177
|
}
|
|
139
178
|
export interface AttemptSessionRow {
|
|
140
179
|
readonly attempt: AttemptId;
|
|
141
180
|
readonly agentSession: AgentSessionId;
|
|
142
181
|
readonly atcSession: AtcSessionId;
|
|
182
|
+
readonly product: Product;
|
|
183
|
+
readonly source: 'worker' | 'hook';
|
|
143
184
|
readonly seenAt: Instant;
|
|
144
185
|
}
|
|
145
186
|
export interface LeaseRow {
|
|
@@ -150,32 +191,40 @@ export interface LeaseRow {
|
|
|
150
191
|
readonly takenAt: Instant;
|
|
151
192
|
readonly releasedAt: Instant | null;
|
|
152
193
|
}
|
|
153
|
-
export interface
|
|
154
|
-
readonly
|
|
155
|
-
readonly
|
|
156
|
-
readonly
|
|
157
|
-
readonly
|
|
158
|
-
readonly
|
|
194
|
+
export interface LimitSeatRow {
|
|
195
|
+
readonly limit: LimitName;
|
|
196
|
+
readonly attempt: AttemptId;
|
|
197
|
+
readonly holdGen: number;
|
|
198
|
+
readonly overCap: boolean;
|
|
199
|
+
readonly takenAt: Instant;
|
|
200
|
+
readonly releasedAt: Instant | null;
|
|
159
201
|
}
|
|
160
202
|
export interface ObservationBoundary {
|
|
161
203
|
readonly storeVersion: number;
|
|
162
204
|
readonly pepysOffsets: Readonly<Record<StreamName, number>>;
|
|
163
205
|
}
|
|
206
|
+
export interface LimitCount {
|
|
207
|
+
readonly limit: LimitName;
|
|
208
|
+
readonly held: number;
|
|
209
|
+
readonly max: number;
|
|
210
|
+
}
|
|
164
211
|
export interface DecisionRow {
|
|
165
212
|
readonly id: DecisionId;
|
|
166
213
|
readonly attempt: AttemptId;
|
|
167
214
|
readonly item: ItemId;
|
|
215
|
+
readonly kind: 'start' | 'wake';
|
|
168
216
|
readonly pool: PoolName;
|
|
169
217
|
readonly rulesVersion: RulesVersion;
|
|
170
218
|
readonly snapshotHash: SnapshotHash;
|
|
171
219
|
readonly storeVersion: number;
|
|
172
220
|
readonly pepysOffsets: ObservationBoundary['pepysOffsets'];
|
|
173
221
|
readonly faults: readonly FaultRecord[];
|
|
222
|
+
readonly limits: readonly LimitCount[];
|
|
174
223
|
readonly at: Instant;
|
|
175
224
|
}
|
|
176
225
|
export interface FaultRecord {
|
|
177
226
|
readonly plugin: string;
|
|
178
|
-
readonly kind: 'signal' | 'gate' | 'waiver' | 'admission' | 'propagation';
|
|
227
|
+
readonly kind: 'signal' | 'gate' | 'waiver' | 'admission' | 'propagation' | 'filter-field';
|
|
179
228
|
readonly item: ItemId | null;
|
|
180
229
|
readonly error: string;
|
|
181
230
|
}
|
|
@@ -193,6 +242,8 @@ export interface PullRequestRow {
|
|
|
193
242
|
readonly repo: RepoName;
|
|
194
243
|
readonly number: number;
|
|
195
244
|
readonly attempt: AttemptId;
|
|
245
|
+
readonly githubId: number;
|
|
246
|
+
readonly url: string;
|
|
196
247
|
readonly state: 'open' | 'closed' | 'merged';
|
|
197
248
|
readonly mergedAt: Instant | null;
|
|
198
249
|
readonly mergeCommit: CommitSha | null;
|
|
@@ -203,6 +254,14 @@ export interface RunnerRow {
|
|
|
203
254
|
readonly heartbeatAt: Instant;
|
|
204
255
|
readonly paused: boolean;
|
|
205
256
|
}
|
|
257
|
+
export interface NoticeRow {
|
|
258
|
+
readonly id: number;
|
|
259
|
+
readonly item: ItemId;
|
|
260
|
+
readonly reason: HoldReason;
|
|
261
|
+
readonly at: Instant;
|
|
262
|
+
readonly tries: number;
|
|
263
|
+
readonly sentAt: Instant | null;
|
|
264
|
+
}
|
|
206
265
|
export type Effort = 'low' | 'medium' | 'high' | 'xhigh' | 'max';
|
|
207
266
|
export interface Recipe {
|
|
208
267
|
readonly agent: string;
|
|
@@ -210,15 +269,14 @@ export interface Recipe {
|
|
|
210
269
|
readonly effort: Effort;
|
|
211
270
|
readonly prompt: string;
|
|
212
271
|
readonly source: SourceName;
|
|
272
|
+
readonly skills: readonly string[];
|
|
213
273
|
}
|
|
214
274
|
export interface RecipeMaterial {
|
|
215
275
|
readonly name: RecipeName;
|
|
216
276
|
readonly recipe: Recipe;
|
|
217
277
|
readonly promptHash: ContentHash;
|
|
218
|
-
readonly pluginFolderHash: ContentHash;
|
|
219
278
|
readonly rulesVersion: RulesVersion;
|
|
220
279
|
}
|
|
221
|
-
export type LoadedRecipe = Omit<RecipeMaterial, 'pluginFolderHash'>;
|
|
222
280
|
export interface ResolvedRecipe extends RecipeMaterial {
|
|
223
281
|
readonly hash: RecipeHash;
|
|
224
282
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function formatKeyPath(segments: readonly PropertyKey[]): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@boxxy/model",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "The types that boxxy's packages share",
|
|
5
5
|
"homepage": "https://github.com/zgeoff/boxxy/tree/main/libs/model#readme",
|
|
6
6
|
"bugs": "https://github.com/zgeoff/boxxy/issues",
|
|
@@ -31,10 +31,21 @@
|
|
|
31
31
|
"typecheck": "tsrs --noEmit"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@boxxy/content-hash": "0.1.
|
|
35
|
-
"
|
|
34
|
+
"@boxxy/content-hash": "0.1.3",
|
|
35
|
+
"tiny-invariant": "1.3.3",
|
|
36
36
|
"zod": "4.6.7"
|
|
37
37
|
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@faker-js/faker": "10.6.0"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"@faker-js/faker": "10.6.0"
|
|
43
|
+
},
|
|
44
|
+
"peerDependenciesMeta": {
|
|
45
|
+
"@faker-js/faker": {
|
|
46
|
+
"optional": true
|
|
47
|
+
}
|
|
48
|
+
},
|
|
38
49
|
"engines": {
|
|
39
50
|
"bun": ">=1.3",
|
|
40
51
|
"node": ">=24"
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { brandSchemas } from '
|
|
2
|
+
import { brandSchemas } from '../rows/brand-schemas.ts';
|
|
3
3
|
import { frictionSchema } from './friction-schema.ts';
|
|
4
|
-
import
|
|
4
|
+
import { openItemSchema } from './open-item-schema.ts';
|
|
5
|
+
import type { BuildCloseOut } from './types.ts';
|
|
5
6
|
|
|
6
7
|
const reasonSchema = z.string().min(1);
|
|
7
8
|
const builtSchema = z.object({ kind: z.literal('built') });
|
|
@@ -13,16 +14,10 @@ const citedEvidenceSchema = z.object({
|
|
|
13
14
|
evidence: brandSchemas.factId,
|
|
14
15
|
});
|
|
15
16
|
|
|
16
|
-
const
|
|
17
|
-
kind: z.literal('core.issue'),
|
|
18
|
-
title: z.string().min(1),
|
|
19
|
-
body: z.string(),
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
export const buildCloseOutSchema: z.ZodType<BuildCloseOut> = z.object({
|
|
17
|
+
export const buildCloseOutSchema = z.strictObject({
|
|
23
18
|
result: z.discriminatedUnion('kind', [builtSchema, blockedSchema, abandonedSchema]),
|
|
24
19
|
criteria: z.array(citedEvidenceSchema),
|
|
25
20
|
openItems: z.array(openItemSchema),
|
|
26
21
|
friction: z.array(frictionSchema),
|
|
27
22
|
frictionDropped: z.number().int().nonnegative(),
|
|
28
|
-
})
|
|
23
|
+
}) satisfies z.ZodType<BuildCloseOut>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { brandSchemas } from '../rows/brand-schemas.ts';
|
|
3
|
+
import type { CloseOutAnswer, CloseOutProblem } from './types.ts';
|
|
4
|
+
|
|
5
|
+
const closeOutProblemSchema: z.ZodType<CloseOutProblem> = z.discriminatedUnion('kind', [
|
|
6
|
+
z.object({ kind: z.literal('schema'), path: z.string(), message: z.string() }),
|
|
7
|
+
z.object({ kind: z.literal('unknown-criterion'), criterion: brandSchemas.criterionId }),
|
|
8
|
+
z.object({ kind: z.literal('foreign-evidence'), evidence: brandSchemas.factId }),
|
|
9
|
+
z.object({
|
|
10
|
+
kind: z.literal('built-without-evidence'),
|
|
11
|
+
criteria: z.array(brandSchemas.criterionId),
|
|
12
|
+
}),
|
|
13
|
+
z.object({ kind: z.literal('no-acceptance') }),
|
|
14
|
+
z.object({ kind: z.literal('unknown-item'), item: z.string() }),
|
|
15
|
+
z.object({ kind: z.literal('unknown-kind'), itemKind: z.string() }),
|
|
16
|
+
z.object({
|
|
17
|
+
kind: z.literal('refused-relation'),
|
|
18
|
+
type: z.string(),
|
|
19
|
+
target: z.string(),
|
|
20
|
+
reason: z.enum(['unknown-type', 'self']),
|
|
21
|
+
}),
|
|
22
|
+
z.object({ kind: z.literal('phase-rule'), message: z.string() }),
|
|
23
|
+
z.object({
|
|
24
|
+
kind: z.literal('too-large'),
|
|
25
|
+
bytes: z.number().int().nonnegative(),
|
|
26
|
+
max: z.number().int().nonnegative(),
|
|
27
|
+
}),
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
export const closeOutAnswerSchema: z.ZodType<CloseOutAnswer> = z.discriminatedUnion('kind', [
|
|
31
|
+
z.object({
|
|
32
|
+
kind: z.literal('recorded'),
|
|
33
|
+
attempt: brandSchemas.attemptId,
|
|
34
|
+
factId: brandSchemas.factId,
|
|
35
|
+
repeat: z.boolean(),
|
|
36
|
+
}),
|
|
37
|
+
z.object({ kind: z.literal('rejected'), problems: z.array(closeOutProblemSchema) }),
|
|
38
|
+
z.object({
|
|
39
|
+
kind: z.literal('refused'),
|
|
40
|
+
reason: z.enum(['no-attempt', 'already-closed-out', 'not-current']),
|
|
41
|
+
}),
|
|
42
|
+
]);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { buildCloseOutSchema } from './build-close-out-schema.ts';
|
|
3
|
+
import { designCloseOutSchema } from './design-close-out-schema.ts';
|
|
4
|
+
import { reviewCloseOutSchema } from './review-close-out-schema.ts';
|
|
5
|
+
import { triageCloseOutSchema } from './triage-close-out-schema.ts';
|
|
6
|
+
import type { CloseOut } from './types.ts';
|
|
7
|
+
|
|
8
|
+
export const closeOutSchema: z.ZodType<CloseOut> = z.union([
|
|
9
|
+
reviewCloseOutSchema,
|
|
10
|
+
triageCloseOutSchema,
|
|
11
|
+
buildCloseOutSchema,
|
|
12
|
+
designCloseOutSchema,
|
|
13
|
+
]);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { frictionSchema } from './friction-schema.ts';
|
|
3
|
+
import type { DesignCloseOut } from './types.ts';
|
|
4
|
+
|
|
5
|
+
const reasonSchema = z.string().min(1);
|
|
6
|
+
|
|
7
|
+
const designRefSchema = z.object({
|
|
8
|
+
summary: z.string().min(1),
|
|
9
|
+
location: z.string().min(1).nullable(),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const designedSchema = z.object({ kind: z.literal('designed'), design: designRefSchema });
|
|
13
|
+
const blockedSchema = z.object({ kind: z.literal('blocked'), reason: reasonSchema });
|
|
14
|
+
const abandonedSchema = z.object({ kind: z.literal('abandoned'), reason: reasonSchema });
|
|
15
|
+
|
|
16
|
+
export const designCloseOutSchema = z.strictObject({
|
|
17
|
+
result: z.discriminatedUnion('kind', [designedSchema, blockedSchema, abandonedSchema]),
|
|
18
|
+
friction: z.array(frictionSchema),
|
|
19
|
+
frictionDropped: z.number().int().nonnegative(),
|
|
20
|
+
}) satisfies z.ZodType<DesignCloseOut>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { Friction } from './types.ts';
|
|
3
|
+
|
|
4
|
+
// A plain object, so that the fact schema of `boxxy.proposal.recorded` can extend it.
|
|
5
|
+
export const frictionSchema = z.object({
|
|
6
|
+
target: z.object({
|
|
7
|
+
kind: z.enum(['skill', 'rule', 'lint', 'agents-md', 'tool']),
|
|
8
|
+
name: z.string().min(1),
|
|
9
|
+
}),
|
|
10
|
+
change: z.string().min(1),
|
|
11
|
+
}) satisfies z.ZodType<Friction>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { brandSchemas } from '../rows/brand-schemas.ts';
|
|
3
|
+
import { frictionSchema } from './friction-schema.ts';
|
|
4
|
+
import type { ReviewCloseOut } from './types.ts';
|
|
5
|
+
|
|
6
|
+
const countSchema = z.number().int().nonnegative();
|
|
7
|
+
|
|
8
|
+
const findingSchema = z.object({
|
|
9
|
+
title: z.string().min(1),
|
|
10
|
+
body: z.string(),
|
|
11
|
+
path: z.string().min(1).exactOptional(),
|
|
12
|
+
line: z.number().int().positive().exactOptional(),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const passedSchema = z.object({ kind: z.literal('passed') });
|
|
16
|
+
|
|
17
|
+
const changesRequestedSchema = z.object({
|
|
18
|
+
kind: z.literal('changes-requested'),
|
|
19
|
+
findings: z.array(findingSchema),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const noslopSummarySchema = z.object({
|
|
23
|
+
version: z.number().int().positive(),
|
|
24
|
+
reviewID: z.string().min(1),
|
|
25
|
+
head: brandSchemas.commitSha,
|
|
26
|
+
counts: z.object({ findings: countSchema, failedCalls: countSchema, fixChecks: countSchema }),
|
|
27
|
+
reportBytes: countSchema,
|
|
28
|
+
report: z.json().nullable(),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// The stored form. The parser of the review phase reads noslop's whole result and builds the
|
|
32
|
+
// summary, so this schema never sees the raw result.
|
|
33
|
+
export const reviewCloseOutSchema = z.strictObject({
|
|
34
|
+
verdict: z.discriminatedUnion('kind', [passedSchema, changesRequestedSchema]),
|
|
35
|
+
noslop: noslopSummarySchema,
|
|
36
|
+
friction: z.array(frictionSchema),
|
|
37
|
+
frictionDropped: countSchema,
|
|
38
|
+
}) satisfies z.ZodType<ReviewCloseOut>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { brandSchemas } from '../rows/brand-schemas.ts';
|
|
3
|
+
import { frictionSchema } from './friction-schema.ts';
|
|
4
|
+
import type { TriageCloseOut } from './types.ts';
|
|
5
|
+
|
|
6
|
+
const acceptedSchema = z.object({ kind: z.literal('accepted') });
|
|
7
|
+
const duplicateSchema = z.object({ kind: z.literal('duplicate'), of: brandSchemas.itemId });
|
|
8
|
+
const declinedSchema = z.object({ kind: z.literal('declined'), reason: z.string().min(1) });
|
|
9
|
+
const designModeSchema = z.enum(['agent', 'attended']);
|
|
10
|
+
const criterionTextSchema = z.object({ text: z.string().min(1) });
|
|
11
|
+
|
|
12
|
+
const setSchema = z.strictObject({
|
|
13
|
+
kind: brandSchemas.itemKindName.exactOptional(),
|
|
14
|
+
designMode: designModeSchema.exactOptional(),
|
|
15
|
+
acceptance: z.array(criterionTextSchema).exactOptional(),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const relationDraftSchema = z.object({
|
|
19
|
+
type: brandSchemas.relationTypeName,
|
|
20
|
+
target: brandSchemas.itemId,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export const triageCloseOutSchema = z.strictObject({
|
|
24
|
+
result: z.discriminatedUnion('kind', [acceptedSchema, duplicateSchema, declinedSchema]),
|
|
25
|
+
set: setSchema.exactOptional(),
|
|
26
|
+
relations: z.array(relationDraftSchema),
|
|
27
|
+
friction: z.array(frictionSchema),
|
|
28
|
+
frictionDropped: z.number().int().nonnegative(),
|
|
29
|
+
}) satisfies z.ZodType<TriageCloseOut>;
|