@nac3/forge-cli 1.9.3 → 1.11.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.
- package/dist/chat/doctrine_digest.d.ts.map +1 -1
- package/dist/chat/doctrine_digest.js +15 -0
- package/dist/chat/doctrine_digest.js.map +1 -1
- package/dist/chat/panel.d.ts.map +1 -1
- package/dist/chat/panel.js +13363 -12980
- package/dist/chat/panel.js.map +1 -1
- package/dist/chat/server.d.ts.map +1 -1
- package/dist/chat/server.js +60 -10
- package/dist/chat/server.js.map +1 -1
- package/dist/chat/sizing_section.d.ts +9 -0
- package/dist/chat/sizing_section.d.ts.map +1 -0
- package/dist/chat/sizing_section.js +73 -0
- package/dist/chat/sizing_section.js.map +1 -0
- package/dist/chat/tools/app_backend_dispatch.d.ts.map +1 -1
- package/dist/chat/tools/app_backend_dispatch.js +46 -0
- package/dist/chat/tools/app_backend_dispatch.js.map +1 -1
- package/dist/chat/tools/pending.d.ts +8 -0
- package/dist/chat/tools/pending.d.ts.map +1 -1
- package/dist/chat/tools/pending.js +26 -0
- package/dist/chat/tools/pending.js.map +1 -1
- package/dist/chat/tools/shell.d.ts +5 -0
- package/dist/chat/tools/shell.d.ts.map +1 -1
- package/dist/chat/tools/shell.js +60 -0
- package/dist/chat/tools/shell.js.map +1 -1
- package/dist/chat/tools/sizing.d.ts +66 -0
- package/dist/chat/tools/sizing.d.ts.map +1 -0
- package/dist/chat/tools/sizing.js +171 -0
- package/dist/chat/tools/sizing.js.map +1 -0
- package/dist/chat/tools.d.ts.map +1 -1
- package/dist/chat/tools.js +25 -2
- package/dist/chat/tools.js.map +1 -1
- package/dist/commands/clarify.d.ts.map +1 -1
- package/dist/commands/clarify.js +163 -1
- package/dist/commands/clarify.js.map +1 -1
- package/dist/commands/pending.d.ts.map +1 -1
- package/dist/commands/pending.js +9 -0
- package/dist/commands/pending.js.map +1 -1
- package/dist/commands/triage.d.ts +61 -7
- package/dist/commands/triage.d.ts.map +1 -1
- package/dist/commands/triage.js +106 -13
- package/dist/commands/triage.js.map +1 -1
- package/dist/core/forge_profile.d.ts +10 -0
- package/dist/core/forge_profile.d.ts.map +1 -1
- package/dist/core/forge_profile.js +6 -0
- package/dist/core/forge_profile.js.map +1 -1
- package/dist/docs/doctrine/gates.md +33 -21
- package/dist/docs/doctrine/sizing.md +182 -0
- package/dist/nac3/backend_tools.d.ts +14 -0
- package/dist/nac3/backend_tools.d.ts.map +1 -1
- package/dist/nac3/backend_tools.js +31 -1
- package/dist/nac3/backend_tools.js.map +1 -1
- package/dist/nac3/internal_manifest.d.ts.map +1 -1
- package/dist/nac3/internal_manifest.js +172 -5
- package/dist/nac3/internal_manifest.js.map +1 -1
- package/dist/pending/commit_files.d.ts +3 -0
- package/dist/pending/commit_files.d.ts.map +1 -0
- package/dist/pending/commit_files.js +42 -0
- package/dist/pending/commit_files.js.map +1 -0
- package/dist/pending/store.d.ts +12 -0
- package/dist/pending/store.d.ts.map +1 -1
- package/dist/pending/store.js +66 -0
- package/dist/pending/store.js.map +1 -1
- package/dist/pending/types.d.ts +50 -0
- package/dist/pending/types.d.ts.map +1 -1
- package/dist/pending/types.js.map +1 -1
- package/dist/sizing/model.d.ts +200 -0
- package/dist/sizing/model.d.ts.map +1 -0
- package/dist/sizing/model.js +423 -0
- package/dist/sizing/model.js.map +1 -0
- package/dist/sizing/store.d.ts +114 -0
- package/dist/sizing/store.d.ts.map +1 -0
- package/dist/sizing/store.js +235 -0
- package/dist/sizing/store.js.map +1 -0
- package/dist/tasks/supervisor.d.ts +21 -0
- package/dist/tasks/supervisor.d.ts.map +1 -1
- package/dist/tasks/supervisor.js +39 -3
- package/dist/tasks/supervisor.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/workflow/definitions.js +1 -1
- package/dist/workflow/definitions.js.map +1 -1
- package/dist/workflow/state.d.ts +28 -0
- package/dist/workflow/state.d.ts.map +1 -1
- package/dist/workflow/state.js.map +1 -1
- package/docs/doctrine/gates.md +33 -21
- package/docs/doctrine/sizing.md +182 -0
- package/package.json +117 -117
- package/src/i18n/catalogs/ar.json +1 -0
- package/src/i18n/catalogs/de.json +1 -0
- package/src/i18n/catalogs/en.json +1 -0
- package/src/i18n/catalogs/es.json +1 -0
- package/src/i18n/catalogs/fr.json +1 -0
- package/src/i18n/catalogs/hi.json +1 -0
- package/src/i18n/catalogs/it.json +1 -0
- package/src/i18n/catalogs/ja.json +1 -0
- package/src/i18n/catalogs/pt.json +1 -0
- package/src/i18n/catalogs/zh.json +1 -0
package/dist/pending/types.d.ts
CHANGED
|
@@ -73,6 +73,10 @@ export interface PendingItem {
|
|
|
73
73
|
* deja una entrada aca. La de cierre (kind='resolution') resume
|
|
74
74
|
* como se resolvio. Append-only. */
|
|
75
75
|
history?: PendingHistoryEntry[];
|
|
76
|
+
/** El expediente de la implementacion (Pablo 2026-10-11). Se completa al
|
|
77
|
+
* cerrar: lo entregado, las fuentes afectadas y los casos de uso. Lo lee la
|
|
78
|
+
* pestana Done. */
|
|
79
|
+
implementation?: PendingImplementation;
|
|
76
80
|
/** PND-094 ext -- set when this item is a TASK of a workflow
|
|
77
81
|
* instance. Stages are NOT pendings; tasks are. An item with a
|
|
78
82
|
* `workflow` block is a "WFL" item. Ad-hoc corrective/evolutive
|
|
@@ -94,6 +98,52 @@ export interface PendingWorkflowLink {
|
|
|
94
98
|
* (not part of the instantiated canonical skeleton). */
|
|
95
99
|
ad_hoc?: boolean;
|
|
96
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* El EXPEDIENTE de la implementacion (Pablo 2026-10-11). Un pending cerrado
|
|
103
|
+
* sin esto es una linea que dice "listo": no sirve para entender despues QUE se
|
|
104
|
+
* entrego, ni para que otro agente lo retome. La pestana Done lo muestra al
|
|
105
|
+
* lado del pedido original.
|
|
106
|
+
*
|
|
107
|
+
* Se arma en DOS mitades, por fuente:
|
|
108
|
+
* - DETERMINISTA: `files` sale del commit que cerro el item (git show
|
|
109
|
+
* --name-only). No se le pregunta al cerebro algo que el repositorio ya
|
|
110
|
+
* sabe con certeza.
|
|
111
|
+
* - DEL CEREBRO: `functional` y `use_cases` -- la descripcion funcional y los
|
|
112
|
+
* casos de uso. Eso no esta en el diff y es lo que un humano necesita leer.
|
|
113
|
+
*/
|
|
114
|
+
export interface PendingImplementation {
|
|
115
|
+
/** Que se hizo, en una o dos frases (el resumen tecnico del cierre). */
|
|
116
|
+
summary?: string;
|
|
117
|
+
/** Descripcion FUNCIONAL completa: que puede hacer ahora el usuario que
|
|
118
|
+
* antes no podia, y como se comporta. */
|
|
119
|
+
functional?: string;
|
|
120
|
+
/** Casos de uso concretos que quedaron cubiertos. */
|
|
121
|
+
use_cases?: string[];
|
|
122
|
+
/** Fuentes afectadas. Derivadas del/los commit/s cuando hay SHA; el cerebro
|
|
123
|
+
* puede agregar las que un commit posterior no refleja. */
|
|
124
|
+
files?: string[];
|
|
125
|
+
/** SHAs que entregaron el trabajo (el del cierre + los que se declaren). */
|
|
126
|
+
commits?: string[];
|
|
127
|
+
/** La VERIFICACION (Pablo 2026-10-11). Que piezas de test cubren esto y como
|
|
128
|
+
* salieron. Los archivos se derivan del commit (los que caen en tests/ o
|
|
129
|
+
* terminan en .test.*); el resultado lo declara quien cierra, porque acaba
|
|
130
|
+
* de correr la suite y el repositorio no guarda ese dato. */
|
|
131
|
+
tests?: PendingTests;
|
|
132
|
+
/** Epoch millis de la ultima vez que se completo este expediente. */
|
|
133
|
+
collected_at: number;
|
|
134
|
+
}
|
|
135
|
+
/** Resultado de la verificacion de un item cerrado. */
|
|
136
|
+
export interface PendingTests {
|
|
137
|
+
/** Piezas de test relacionadas (rutas). */
|
|
138
|
+
files?: string[];
|
|
139
|
+
/** Como salio: green = todo pasa; red = quedo algo rojo; partial = cubierto
|
|
140
|
+
* en parte; none = se cerro sin tests (valido, pero queda dicho). */
|
|
141
|
+
status?: 'green' | 'red' | 'partial' | 'none';
|
|
142
|
+
/** El detalle en una linea: "forge-operate 49 passed", "4 suites, 1 skip". */
|
|
143
|
+
summary?: string;
|
|
144
|
+
/** Epoch millis de cuando se corrio. */
|
|
145
|
+
at?: number;
|
|
146
|
+
}
|
|
97
147
|
/** Una entrada del history del item (gestion + ciclo iterativo). */
|
|
98
148
|
export interface PendingHistoryEntry {
|
|
99
149
|
/** Epoch millis. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/pending/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,6CAA6C;AAC7C,MAAM,MAAM,eAAe,GACvB,cAAc,GACd,WAAW,GACX,SAAS,GACT,KAAK,GACL,OAAO,CAAC;AAEZ,6BAA6B;AAC7B,MAAM,MAAM,kBAAkB,GAC1B,SAAS,GACT,WAAW,GACX,WAAW,GACX,UAAU,CAAC;AAEf;;4CAE4C;AAC5C,MAAM,MAAM,kBAAkB,GAC1B,eAAe,GACf,iBAAiB,GACjB,cAAc,GACd,kBAAkB,CAAC;AAEvB,6CAA6C;AAC7C,MAAM,WAAW,WAAW;IAC1B,uDAAuD;IACvD,EAAE,EAAE,MAAM,CAAC;IACX,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,QAAQ,EAAE,eAAe,CAAC;IAC1B,wDAAwD;IACxD,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC;iEAC6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;mCAC+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC;oEACgE;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;6CAEyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;yCAGqC;IACrC,OAAO,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAChC;;;;iCAI6B;IAC7B,QAAQ,CAAC,EAAE,mBAAmB,CAAC;CAChC;AAED,uEAAuE;AACvE,MAAM,WAAW,mBAAmB;IAClC,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,IAAI,EAAE,YAAY,GAAG,YAAY,GAAG,WAAW,CAAC;IAChD,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;IACd;6DACyD;IACzD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,oEAAoE;AACpE,MAAM,WAAW,mBAAmB;IAClC,oBAAoB;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb;qDACiD;IACjD,IAAI,EAAE,UAAU,GAAG,WAAW,GAAG,YAAY,GAAG,YAAY,CAAC;CAC9D;AAED;qDACqD;AACrD,MAAM,WAAW,WAAW;IAC1B;6BACyB;IACzB,OAAO,EAAE,CAAC,CAAC;IACX;yDACqD;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB;0DACsD;IACtD,OAAO,EAAE,MAAM,CAAC;IAChB;oBACgB;IAChB,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,wCAAwC;AACxC,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,WAAW,CAOlE;AAED,wCAAwC;AACxC,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED,wDAAwD;AACxD,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMxD;AAED,gEAAgE;AAChE,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,CAEnD"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/pending/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/pending/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/pending/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAuKH,wCAAwC;AACxC,MAAM,UAAU,gBAAgB,CAAC,YAAoB;IACnD,OAAO;QACL,OAAO,EAAO,CAAC;QACf,YAAY;QACZ,OAAO,EAAO,CAAC;QACf,KAAK,EAAS,EAAE;KACjB,CAAC;AACJ,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,eAAe,CAAC,CAAS;IACvC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,oDAAoD,GAAG,CAAC,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC7C,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,MAAM,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjC,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,OAAO,CAAC,CAAC;AACX,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,mBAAmB,CAAC,CAAQ;IAC1C,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SIZING MODEL -- fixed architecture options with validity envelopes.
|
|
3
|
+
*
|
|
4
|
+
* Why this exists (Pablo, 2026-10-11, after the ADIP-KIKAN post mortem).
|
|
5
|
+
*
|
|
6
|
+
* docs/doctrine/concurrency-scale.md already said the right thing on its
|
|
7
|
+
* first line: "Every application Forge designs MUST be sized ... Scale is
|
|
8
|
+
* a RELEVAMIENTO input, not an afterthought bolted on when the app falls
|
|
9
|
+
* over." ADIP-KIKAN was built anyway with its whole working set resident
|
|
10
|
+
* in the Node heap. At its real volumetry (5.000 affiliates x 40 campaigns
|
|
11
|
+
* per year -> ~3,4M rows/year -> ~8 GB of live heap per year against a
|
|
12
|
+
* 2-4 GB V8 ceiling) that design hits a wall in months.
|
|
13
|
+
*
|
|
14
|
+
* So the lesson is NOT "write more doctrine". The doctrine was there and
|
|
15
|
+
* it was prose, and prose is advisory. Four concrete holes made the
|
|
16
|
+
* failure possible, and this module closes the first three:
|
|
17
|
+
*
|
|
18
|
+
* 1. The only volumetry Forge asked for was PEAK CONCURRENCY
|
|
19
|
+
* (src/commands/triage.ts), used solely to pick a complexity tier.
|
|
20
|
+
* Kikan has 100 concurrent users -- a low number -- and died of ROW
|
|
21
|
+
* COUNT. Data volume x retention was never a question.
|
|
22
|
+
* 2. There was no HARDWARE envelope at all: no RAM, no runtime heap
|
|
23
|
+
* ceiling, no disk. The architecture was chosen without knowing the
|
|
24
|
+
* machine, and the ceiling that kills the process (V8's
|
|
25
|
+
* heap_size_limit) is a property of the machine + runtime, not of the
|
|
26
|
+
* business.
|
|
27
|
+
* 3. The architecture choice was FREE-FORM. Forge invented an approach
|
|
28
|
+
* and wrote a rationale; there was no fixed option set with validity
|
|
29
|
+
* ranges, so there was nothing to violate.
|
|
30
|
+
* 4. The only gate touching volumetry was SOFT (gates.md GS4), and soft
|
|
31
|
+
* gates do not block. That one is closed by the hard gate in
|
|
32
|
+
* src/sizing/store.ts + the G9 entry in docs/doctrine/gates.md.
|
|
33
|
+
*
|
|
34
|
+
* The shape of the fix, consistent with the project's own rule that rules
|
|
35
|
+
* are ENFORCEMENT and not prompt: the numbers are DERIVED here from
|
|
36
|
+
* declared inputs, each architecture option declares the envelope in
|
|
37
|
+
* which it is admissible, and choosing outside the envelope is a REJECTED
|
|
38
|
+
* call -- not a judgement the brain can argue its way out of.
|
|
39
|
+
*
|
|
40
|
+
* This module is pure: no I/O, no process state. Persistence and the gate
|
|
41
|
+
* live in ./store.ts.
|
|
42
|
+
*
|
|
43
|
+
* ASCII-only.
|
|
44
|
+
*/
|
|
45
|
+
/** One business entity and the event traffic it generates. */
|
|
46
|
+
export interface EntityVolume {
|
|
47
|
+
/** Business name, as the owner says it: "afiliados", "clientes". */
|
|
48
|
+
name: string;
|
|
49
|
+
/** How many exist at the declared horizon. */
|
|
50
|
+
count: number;
|
|
51
|
+
/** Events per entity per year (a campaign, an order, a visit). */
|
|
52
|
+
events_per_year: number;
|
|
53
|
+
/**
|
|
54
|
+
* Rows each event leaves, summed over EVERY table it touches.
|
|
55
|
+
* This is the number people get wrong: in Kikan one campaign-affiliate
|
|
56
|
+
* event leaves ~15-20 rows (pending + dispatch items + messages +
|
|
57
|
+
* traces + run events), not one.
|
|
58
|
+
*/
|
|
59
|
+
rows_per_event: number;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Retention per data CLASS. The distinction matters because it is the one
|
|
63
|
+
* Kikan never made: business data (the conversation with the family) and
|
|
64
|
+
* trace data (how the pipeline processed it) have completely different
|
|
65
|
+
* retention rights, and lumping them together is what makes a system
|
|
66
|
+
* grow forever.
|
|
67
|
+
*
|
|
68
|
+
* 0 means "kept forever" -- which is the inert default that burned Kikan
|
|
69
|
+
* (observability/logging.js shipped max_events 0 / max_days 0).
|
|
70
|
+
*/
|
|
71
|
+
export interface Retention {
|
|
72
|
+
business_days: number;
|
|
73
|
+
trace_days: number;
|
|
74
|
+
}
|
|
75
|
+
/** The machine and runtime the thing actually runs on. */
|
|
76
|
+
export interface Hardware {
|
|
77
|
+
ram_mb: number;
|
|
78
|
+
/**
|
|
79
|
+
* Runtime heap ceiling in MB. For Node this is V8's heap_size_limit
|
|
80
|
+
* (~2048-4096 by default on 64-bit), NOT the RAM of the VM. Getting
|
|
81
|
+
* this wrong by using RAM is the specific mistake that makes an
|
|
82
|
+
* in-memory design look survivable.
|
|
83
|
+
*/
|
|
84
|
+
heap_cap_mb: number;
|
|
85
|
+
disk_gb: number;
|
|
86
|
+
vcpus: number;
|
|
87
|
+
}
|
|
88
|
+
export interface SizingInput {
|
|
89
|
+
entities: EntityVolume[];
|
|
90
|
+
/** Average retained bytes per row in the RUNTIME (not on disk). */
|
|
91
|
+
bytes_per_row: number;
|
|
92
|
+
/** Fraction of rows that are trace/log rather than business (0..1). */
|
|
93
|
+
trace_share: number;
|
|
94
|
+
retention: Retention;
|
|
95
|
+
/** Peak simultaneous users / requests. */
|
|
96
|
+
peak_concurrency: number;
|
|
97
|
+
hardware: Hardware;
|
|
98
|
+
/** Years the sizing covers. */
|
|
99
|
+
horizon_years: number;
|
|
100
|
+
/**
|
|
101
|
+
* Reference to a MEASUREMENT that justifies a cache. Free text, but it
|
|
102
|
+
* must name where the number came from. Without it the cache options
|
|
103
|
+
* are inadmissible -- a cache added on a hunch is how you get two
|
|
104
|
+
* sources of truth for free.
|
|
105
|
+
*/
|
|
106
|
+
measured_hotspot?: string;
|
|
107
|
+
}
|
|
108
|
+
export interface Derived {
|
|
109
|
+
rows_per_year: number;
|
|
110
|
+
rows_at_horizon: number;
|
|
111
|
+
/** Rows still alive after retention is applied. */
|
|
112
|
+
live_rows: number;
|
|
113
|
+
live_business_rows: number;
|
|
114
|
+
live_trace_rows: number;
|
|
115
|
+
/** Heap the live set would occupy if it were resident, in MB. */
|
|
116
|
+
heap_mb_if_resident: number;
|
|
117
|
+
/** That, as a percentage of the runtime heap ceiling. */
|
|
118
|
+
heap_pct_if_resident: number;
|
|
119
|
+
/** Disk at the horizon including an index/overhead factor, in GB. */
|
|
120
|
+
disk_gb_at_horizon: number;
|
|
121
|
+
disk_pct_at_horizon: number;
|
|
122
|
+
/** True when ANY data class is kept forever. */
|
|
123
|
+
unbounded: boolean;
|
|
124
|
+
/** Which classes are unbounded, for the message. */
|
|
125
|
+
unbounded_classes: string[];
|
|
126
|
+
}
|
|
127
|
+
export declare function derive(input: SizingInput): Derived;
|
|
128
|
+
export declare const AXES: readonly ["state_residency", "pagination", "retention", "write_concurrency"];
|
|
129
|
+
export type Axis = (typeof AXES)[number];
|
|
130
|
+
export declare const AXIS_LABEL: Record<Axis, string>;
|
|
131
|
+
/** What an envelope predicate gets to look at. */
|
|
132
|
+
export interface EnvelopeCtx {
|
|
133
|
+
input: SizingInput;
|
|
134
|
+
derived: Derived;
|
|
135
|
+
/** The full choice set, so an envelope can depend on another axis. */
|
|
136
|
+
choices: Partial<Record<Axis, string>>;
|
|
137
|
+
}
|
|
138
|
+
export interface EnvelopeVerdict {
|
|
139
|
+
ok: boolean;
|
|
140
|
+
/** Why it is (in)admissible, in one sentence the owner can read. */
|
|
141
|
+
reason: string;
|
|
142
|
+
}
|
|
143
|
+
export interface ArchOption {
|
|
144
|
+
id: string;
|
|
145
|
+
axis: Axis;
|
|
146
|
+
label: string;
|
|
147
|
+
/** What the option actually is. */
|
|
148
|
+
what: string;
|
|
149
|
+
/** The envelope: when is this option allowed to be chosen. */
|
|
150
|
+
envelope: (ctx: EnvelopeCtx) => EnvelopeVerdict;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* The share of the heap ceiling a resident working set may occupy.
|
|
154
|
+
*
|
|
155
|
+
* 25% and not 80%: the heap also holds every request in flight, the
|
|
156
|
+
* declarative catalog, the HTTP buffers and V8's own slack, and
|
|
157
|
+
* mark-compact pauses grow with the LIVE set long before the ceiling is
|
|
158
|
+
* reached -- the system gets unusable before it crashes. A quarter is the
|
|
159
|
+
* line where a resident set is a cache and not a liability.
|
|
160
|
+
*/
|
|
161
|
+
export declare const RESIDENT_HEAP_PCT_MAX = 25;
|
|
162
|
+
/** Above this many rows an in-memory page slice stops being honest. */
|
|
163
|
+
export declare const IN_MEMORY_PAGE_ROWS_MAX = 100000;
|
|
164
|
+
/** Above this share of the disk, "keep everything forever" is a plan to run out. */
|
|
165
|
+
export declare const RETENTION_NONE_DISK_PCT_MAX = 25;
|
|
166
|
+
export declare const OPTIONS: readonly ArchOption[];
|
|
167
|
+
export declare function optionsForAxis(axis: Axis): ArchOption[];
|
|
168
|
+
export declare function findOption(id: string): ArchOption | undefined;
|
|
169
|
+
export interface AxisVerdict {
|
|
170
|
+
axis: Axis;
|
|
171
|
+
chosen?: string;
|
|
172
|
+
ok: boolean;
|
|
173
|
+
reason: string;
|
|
174
|
+
/** Every option whose envelope admits this sizing. */
|
|
175
|
+
admissible: string[];
|
|
176
|
+
}
|
|
177
|
+
export interface SizingVerdict {
|
|
178
|
+
ok: boolean;
|
|
179
|
+
derived: Derived;
|
|
180
|
+
axes: AxisVerdict[];
|
|
181
|
+
/** Input problems that make the whole record unusable. */
|
|
182
|
+
input_errors: string[];
|
|
183
|
+
/** The choice set this sizing would admit, for a proposal. */
|
|
184
|
+
recommended: Record<Axis, string>;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Reject an input that decides nothing. A record of zeros would otherwise
|
|
188
|
+
* pass every envelope and the gate would become a formality -- which is
|
|
189
|
+
* exactly the failure mode being fixed, one level up.
|
|
190
|
+
*/
|
|
191
|
+
export declare function validateInput(input: SizingInput): string[];
|
|
192
|
+
/** The choice set this sizing admits, preferring the safest option. */
|
|
193
|
+
export declare function recommend(input: SizingInput, derived: Derived): Record<Axis, string>;
|
|
194
|
+
/**
|
|
195
|
+
* Validate a full choice set. Fail-closed on every axis: an axis with no
|
|
196
|
+
* choice, an unknown option, or an option outside its envelope all fail.
|
|
197
|
+
*/
|
|
198
|
+
export declare function validateChoices(input: SizingInput, choices: Partial<Record<Axis, string>>): SizingVerdict;
|
|
199
|
+
export declare function renderDerived(d: Derived): string[];
|
|
200
|
+
//# sourceMappingURL=model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/sizing/model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAMH,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,eAAe,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,0DAA0D;AAC1D,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,mEAAmE;IACnE,aAAa,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,SAAS,CAAC;IACrB,0CAA0C;IAC1C,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,+BAA+B;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAMD,MAAM,WAAW,OAAO;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,iEAAiE;IACjE,mBAAmB,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qEAAqE;IACrE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gDAAgD;IAChD,SAAS,EAAE,OAAO,CAAC;IACnB,oDAAoD;IACpD,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAOD,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CA6ClD;AAiBD,eAAO,MAAM,IAAI,8EAA+E,CAAC;AACjG,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzC,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAK3C,CAAC;AAEF,kDAAkD;AAClD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,sEAAsE;IACtE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,QAAQ,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,eAAe,CAAC;CACjD;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC,uEAAuE;AACvE,eAAO,MAAM,uBAAuB,SAAU,CAAC;AAE/C,oFAAoF;AACpF,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAK9C,eAAO,MAAM,OAAO,EAAE,SAAS,UAAU,EAqLxC,CAAC;AAEF,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,EAAE,CAEvD;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAE7D;AAMD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,0DAA0D;IAC1D,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;CACnC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,EAAE,CA2C1D;AAED,uEAAuE;AACvE,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAapF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,GACrC,aAAa,CAiCf;AAMD,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,EAAE,CAWlD"}
|