mirror of
https://github.com/hanzoai/kai.git
synced 2026-10-17 11:18:06 +00:00
army: the JLTV SysML v2 trade and the DDT auxiliary power decision, run against kai-1.3
Two Decision Programs for Army SBIR ARM26BX06-NV012, each with its evidence, the recorded run (kai-1.3, 2026-10-15, `kai serve` on CPU with no network) and run.py, which asks every Kai question of the program on api.hanzo.ai and prints it beside the recorded answer. Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
@@ -13,6 +13,11 @@ the answers you declared, and writes no text.
|
||||
Everything below was measured against production on 2026-10-09, with `routing.checkpoint`
|
||||
reading `kai-1.2`.
|
||||
|
||||
## Army demonstrations
|
||||
|
||||
[`army/`](army/): two ground-vehicle decisions run as programs with Kai answering live, a SysML v2
|
||||
trade (`army/jltv`) and a DDT readiness gate with refresh (`army/apu`), with every recorded output.
|
||||
|
||||
## Questions and answers
|
||||
|
||||
| `type` | you send | Kai returns in `answers.<name>` |
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# Army demonstrations: decisions as programs, Kai inside DDT's gates
|
||||
|
||||
Two ground-vehicle decisions for Army SBIR ARM26BX06-NV012 / STTR ARM26TX06-NV003, each a
|
||||
Decision Program run end to end with Kai answering live over `POST /v1/decisions`. Every Kai
|
||||
probability below is production kai-1.3's (weights `0834a74f…`, calibration
|
||||
`cal_e23c27a1f768bff7`), recorded 2026-10-15 against `kai serve` on CPU with no network, and
|
||||
reproduced the same day on api.hanzo.ai (`run.py`).
|
||||
|
||||
| | `jltv/` | `apu/` |
|
||||
|---|---|---|
|
||||
| Decision | JLTV powertrain: fielded diesel or eJLTV hybrid | Auxiliary power: integrated APU, battery pack or trailer genset |
|
||||
| Evidence | `ltv.sysml`, a SysML v2 model whose every figure cites a public source (W1–C2 in its header) | DDT decision `DEC-SPH-0412`: charter, sealed thermal Evaluation Run, service bulletin, PLM BOM, DDT readiness verdict (values constructed) |
|
||||
| Shows | SysML v2 elements as evidence; Kai reads each option's own status; break-evens; a recorded human hold | DDT's gate as the base verdict; constraints; break-evens; refresh that reruns only what a change reaches |
|
||||
|
||||
Each directory holds the program (`*@1.json`), `evidence.json`, the recorded run
|
||||
(`recorded.json`: every node's output, Kai's full distributions, ranking, flips, gate rulings,
|
||||
bias findings, revisions, the replay manifest and the package's SHA-256), and for `apu` the
|
||||
changes it refreshes on (`changes/`) and the `/v1/decisions` body of its program-scope questions
|
||||
(`request.json`).
|
||||
|
||||
## jltv: SysML v2 trade
|
||||
|
||||
| Kai question | diesel | hybrid |
|
||||
|---|---|---|
|
||||
| Fielded and in production, rather than a demonstrator? (each option reads its own status elements: `LTV::Diesel`; `LTV::Hybrid`, `LTV::maturity`) | P .734 | P .264 |
|
||||
|
||||
Selection: diesel, utility .60 against .40. It flips to the hybrid when the fuel-economy or the
|
||||
field-capability weight rises from .20 to .40. Anchoring check on the decision brief: P .336,
|
||||
not raised. The program manager's recorded hold: "the fuel gain is a company figure (O2); ask
|
||||
for duty-cycle data." The brief and the hold are recorded examples, not model output.
|
||||
|
||||
## apu: readiness gate and refresh
|
||||
|
||||
| Run | DDT gate | Result | Kai | Steps run |
|
||||
|---|---|---|---|---|
|
||||
| Complete evidence | allow | A2 battery .640 > A3 genset .473 > A1 APU .147 | missing evidence .005, conflict .069, anchoring .121 | 10 of 10, 1.47 s |
|
||||
| A2's thermal run withheld | deny | stopped; A2 fails qualification, A3 .875 leads | missing evidence .005 | 6 of 10, 1.30 s |
|
||||
| Bulletin TSB-22 rev B: A2 end-of-life endurance 8.1 → 7.1 h, repair 3 → 6 h | allow | A3 .875; A2 fails the 8 h constraint | conflict .055 | 7 of 10, 1.40 s |
|
||||
|
||||
Break-evens in the first run: A2 holds until the silent-watch weight passes .284 (set .15), the
|
||||
maintenance-burden weight falls below .205 (.35), the cost weight passes .505 (.20), or A2's
|
||||
end-of-life endurance falls below 8.0 h, which the bulletin delivers. DDT's deterministic gate
|
||||
and the program's constraints carried both changes; Kai's missing-evidence and conflict checks
|
||||
stayed under their thresholds, the measured target of the Phase I evidence-reading work.
|
||||
|
||||
## Run
|
||||
|
||||
```bash
|
||||
HANZO_API_KEY=... python3 army/run.py jltv
|
||||
HANZO_API_KEY=... python3 army/run.py apu
|
||||
```
|
||||
|
||||
`run.py` asks each Kai question of the program the way the runtime does (an option-scope
|
||||
question once per option, reading that option's own evidence) and prints the answer beside the
|
||||
recorded one.
|
||||
@@ -0,0 +1,330 @@
|
||||
{
|
||||
"id": "apu.select",
|
||||
"version": 1,
|
||||
"description": "Auxiliary power for a representative ground vehicle (DDT decision DEC-SPH-0412): an integrated APU, a battery-only pack or a trailer genset, for at least 8 h of silent watch at 3.5 kW and 49 C ambient with the lowest field-maintenance burden. The evidence is constructed for the demonstration, not program data; each piece names the DDT object it stands for. Weights are an analyst's example. The readiness verdict is DDT's deterministic gate (base); Thermal qualification is read from the sealed run, not asked of Kai. Kai's checks may tighten the gate, never loosen it. No node commits: the Chief Engineer does, in DDT, after the gate.",
|
||||
"options": [
|
||||
{
|
||||
"id": "A1",
|
||||
"label": "integrated APU",
|
||||
"attributes": {
|
||||
"watch": 10.0,
|
||||
"qual": 1,
|
||||
"bat": 0,
|
||||
"mtbf": 2100,
|
||||
"mttr": 6,
|
||||
"mass": 380,
|
||||
"base_cost": 145,
|
||||
"kwh": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "A2",
|
||||
"label": "battery-only pack, 46 kWh",
|
||||
"attributes": {
|
||||
"watch": 0,
|
||||
"qual": 0,
|
||||
"bat": 1,
|
||||
"mtbf": 6000,
|
||||
"mttr": 0,
|
||||
"mass": 920,
|
||||
"base_cost": 61,
|
||||
"kwh": 46
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "A3",
|
||||
"label": "trailer genset",
|
||||
"attributes": {
|
||||
"watch": 24.0,
|
||||
"qual": 1,
|
||||
"bat": 0,
|
||||
"mtbf": 1500,
|
||||
"mttr": 4,
|
||||
"mass": 1450,
|
||||
"base_cost": 38,
|
||||
"kwh": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"metrics": [
|
||||
{
|
||||
"id": "endurance",
|
||||
"node": "endurance",
|
||||
"unit": "h",
|
||||
"description": "silent watch at 3.5 kW and 49 C: RUN_THERMAL_SWEEP_0007, the battery pack's at end of life per its bulletin"
|
||||
},
|
||||
{
|
||||
"id": "burden",
|
||||
"node": "burden",
|
||||
"unit": "h per 1,000 h",
|
||||
"description": "field-maintenance hours per 1,000 operating hours: MTTR x 1,000 / MTBF"
|
||||
},
|
||||
{
|
||||
"id": "cost",
|
||||
"node": "cost",
|
||||
"unit": "thousand USD",
|
||||
"description": "unit cost (PLM BOM R2026.08)"
|
||||
},
|
||||
{
|
||||
"id": "mass",
|
||||
"node": "mass",
|
||||
"unit": "lb",
|
||||
"description": "mass added or towed"
|
||||
},
|
||||
{
|
||||
"id": "qualified",
|
||||
"node": "qualified",
|
||||
"description": "1 when the sealed thermal run records the option's qualification as passed"
|
||||
}
|
||||
],
|
||||
"objectives": [
|
||||
{
|
||||
"id": "OBJ_SILENT_WATCH",
|
||||
"metric": "endurance",
|
||||
"weight": 0.15,
|
||||
"direction": "max"
|
||||
},
|
||||
{
|
||||
"id": "OBJ_SUSTAINMENT_BURDEN",
|
||||
"metric": "burden",
|
||||
"weight": 0.35,
|
||||
"direction": "min"
|
||||
},
|
||||
{
|
||||
"id": "OBJ_COST",
|
||||
"metric": "cost",
|
||||
"weight": 0.2,
|
||||
"direction": "min"
|
||||
},
|
||||
{
|
||||
"id": "OBJ_MASS",
|
||||
"metric": "mass",
|
||||
"weight": 0.1,
|
||||
"direction": "min"
|
||||
}
|
||||
],
|
||||
"constraints": [
|
||||
{
|
||||
"id": "silent_watch",
|
||||
"metric": "endurance",
|
||||
"op": ">=",
|
||||
"bound": 8
|
||||
},
|
||||
{
|
||||
"id": "thermal_qualified",
|
||||
"metric": "qualified",
|
||||
"op": ">=",
|
||||
"bound": 1
|
||||
}
|
||||
],
|
||||
"assumptions": [
|
||||
{
|
||||
"id": "A2_WATCH_H",
|
||||
"value": 8.1,
|
||||
"range": [
|
||||
6.5,
|
||||
9.0
|
||||
],
|
||||
"confidence": 0.7,
|
||||
"evidence": "techdata",
|
||||
"description": "The battery pack's silent watch at 3.5 kW and 49 C at end of life, from its technical service bulletin's current revision."
|
||||
},
|
||||
{
|
||||
"id": "A2_QUALIFIED",
|
||||
"value": 1,
|
||||
"range": [
|
||||
0,
|
||||
1
|
||||
],
|
||||
"confidence": 0.9,
|
||||
"evidence": "thermal",
|
||||
"description": "1 when the sealed thermal run records A2's qualification as passed, else 0."
|
||||
},
|
||||
{
|
||||
"id": "BATTERY_MTTR_H",
|
||||
"value": 3,
|
||||
"range": [
|
||||
2,
|
||||
8
|
||||
],
|
||||
"confidence": 0.7,
|
||||
"evidence": "techdata",
|
||||
"description": "Hours to repair the battery pack in the field, from its technical service bulletin's current revision."
|
||||
},
|
||||
{
|
||||
"id": "BATTERY_USD_PER_KWH",
|
||||
"value": 520,
|
||||
"range": [
|
||||
380,
|
||||
640
|
||||
],
|
||||
"confidence": 0.6,
|
||||
"evidence": "bom",
|
||||
"description": "Battery pack price per kWh in the BOM's cost basis."
|
||||
}
|
||||
],
|
||||
"bias": [
|
||||
{
|
||||
"id": "anchoring",
|
||||
"check": "Does the charter favor one option before the options were measured?",
|
||||
"node": "anchor"
|
||||
}
|
||||
],
|
||||
"evidence": [
|
||||
{
|
||||
"id": "charter",
|
||||
"uri": "ddt:DEC-SPH-0412/need",
|
||||
"description": "the Chief Engineer's charter: scope, objectives, the gate's requirements"
|
||||
},
|
||||
{
|
||||
"id": "thermal",
|
||||
"uri": "run://RUN_THERMAL_SWEEP_0007",
|
||||
"description": "the sealed thermal Evaluation Run, one result per option, keyed by option"
|
||||
},
|
||||
{
|
||||
"id": "techdata",
|
||||
"uri": "techdata://sph/tsb/22",
|
||||
"description": "the battery pack's technical service bulletin: end-of-life endurance and repair time"
|
||||
},
|
||||
{
|
||||
"id": "bom",
|
||||
"uri": "plm://sph/BOM/[email protected]",
|
||||
"description": "the released BOM's masses and prices"
|
||||
},
|
||||
{
|
||||
"id": "base",
|
||||
"uri": "ddt:DCP_CONCEPT_STRATEGY_HIGH_STAKES/readiness",
|
||||
"description": "DDT's deterministic readiness verdict for the concept gate"
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "endurance",
|
||||
"kind": "expr",
|
||||
"expr": "watch * (1 - bat) + A2_WATCH_H * bat",
|
||||
"inputs": [
|
||||
"A2_WATCH_H"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "burden",
|
||||
"kind": "expr",
|
||||
"inputs": [
|
||||
"BATTERY_MTTR_H"
|
||||
],
|
||||
"expr": "(mttr * (1 - bat) + BATTERY_MTTR_H * bat) * 1000 / mtbf"
|
||||
},
|
||||
{
|
||||
"id": "cost",
|
||||
"kind": "expr",
|
||||
"inputs": [
|
||||
"BATTERY_USD_PER_KWH"
|
||||
],
|
||||
"expr": "base_cost + kwh * BATTERY_USD_PER_KWH / 1000"
|
||||
},
|
||||
{
|
||||
"id": "mass",
|
||||
"kind": "expr",
|
||||
"expr": "mass"
|
||||
},
|
||||
{
|
||||
"id": "qualified",
|
||||
"kind": "expr",
|
||||
"inputs": [
|
||||
"A2_QUALIFIED"
|
||||
],
|
||||
"expr": "qual * (1 - bat) + A2_QUALIFIED * bat"
|
||||
},
|
||||
{
|
||||
"id": "missing",
|
||||
"kind": "kai",
|
||||
"inputs": [
|
||||
"charter",
|
||||
"thermal",
|
||||
"techdata",
|
||||
"bom"
|
||||
],
|
||||
"model": "kai",
|
||||
"question": {
|
||||
"type": "noul",
|
||||
"instructions": "Is a test result or review that the charter requires missing for any option?"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "conflict",
|
||||
"kind": "kai",
|
||||
"inputs": [
|
||||
"charter",
|
||||
"thermal",
|
||||
"techdata",
|
||||
"bom"
|
||||
],
|
||||
"model": "kai",
|
||||
"question": {
|
||||
"type": "noul",
|
||||
"instructions": "Does the technical data disagree with the thermal qualification result?"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "best",
|
||||
"kind": "kai",
|
||||
"inputs": [
|
||||
"charter",
|
||||
"thermal",
|
||||
"techdata",
|
||||
"bom"
|
||||
],
|
||||
"model": "kai",
|
||||
"question": {
|
||||
"type": "choice",
|
||||
"instructions": "Which option best meets the charter: at least 8 hours of silent watch with the lowest field-maintenance burden?",
|
||||
"criteria": {
|
||||
"A1": "integrated APU",
|
||||
"A2": "battery-only pack",
|
||||
"A3": "trailer genset"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "anchor",
|
||||
"kind": "kai",
|
||||
"inputs": [
|
||||
"charter",
|
||||
"thermal",
|
||||
"techdata",
|
||||
"bom"
|
||||
],
|
||||
"model": "kai",
|
||||
"question": {
|
||||
"type": "noul",
|
||||
"instructions": "Does the charter favor one option before the options were measured?"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "readiness",
|
||||
"kind": "policy",
|
||||
"inputs": [
|
||||
"missing",
|
||||
"conflict",
|
||||
"base"
|
||||
],
|
||||
"mode": "enforced",
|
||||
"escalate": {
|
||||
"missing": "ask",
|
||||
"conflict": "ask"
|
||||
},
|
||||
"thresholds": {
|
||||
"missing": 0.5,
|
||||
"conflict": 0.5
|
||||
},
|
||||
"base": "base"
|
||||
}
|
||||
],
|
||||
"refresh": {
|
||||
"on": [
|
||||
"thermal",
|
||||
"techdata",
|
||||
"bom"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "TSB-22 revision B: end-of-life endurance falls to 7.1 h, repair time doubles",
|
||||
"evidence": {
|
||||
"techdata": {
|
||||
"bulletin": "TSB-22",
|
||||
"revision": "B",
|
||||
"component": "A2 battery-only pack, 46 kWh",
|
||||
"silent_watch_h_end_of_life": 7.1,
|
||||
"capacity_fade_pct": 12,
|
||||
"mtbf_h": 6000,
|
||||
"mttr_h": 6,
|
||||
"basis": "fleet field data: 12% capacity fade after 500 cycles at 49 C, 7.1 h observed against the qualification run's 8.1 h; cell-module replacement takes 6 h, not 3",
|
||||
"review": "pending"
|
||||
}
|
||||
},
|
||||
"assumptions": {
|
||||
"A2_WATCH_H": 7.1,
|
||||
"BATTERY_MTTR_H": 6
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "A2's thermal qualification withheld",
|
||||
"evidence": {
|
||||
"thermal": {
|
||||
"A1": "RUN_THERMAL_SWEEP_0007 (thermal model v4.2, sealed; 3.5 kW load, 49 C ambient, 8 h required): complete. 10.0 h of silent watch, 6 C margin. Pass.",
|
||||
"A2": "RUN_THERMAL_SWEEP_0007 (thermal model v4.2, sealed; 3.5 kW load, 49 C ambient, 8 h required): not run for this option. No result.",
|
||||
"A3": "RUN_THERMAL_SWEEP_0007 (thermal model v4.2, sealed; 3.5 kW load, 49 C ambient, 8 h required): complete. 24.0 h of silent watch, 9 C margin. Pass."
|
||||
},
|
||||
"base": "deny"
|
||||
},
|
||||
"assumptions": {
|
||||
"A2_QUALIFIED": 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"charter": {
|
||||
"decision": "DEC-SPH-0412",
|
||||
"need": "Select the auxiliary power source for the vehicle concept: at least 8 hours of silent watch at 3.5 kW and 49 C ambient, with the lowest field-maintenance burden at acceptable cost and mass.",
|
||||
"options": {
|
||||
"A1": "integrated APU",
|
||||
"A2": "battery-only pack, 46 kWh",
|
||||
"A3": "trailer genset"
|
||||
},
|
||||
"gate": "Before the concept gate every option needs a completed thermal qualification run and a reliability review of its current technical data."
|
||||
},
|
||||
"thermal": {
|
||||
"A1": "RUN_THERMAL_SWEEP_0007 (thermal model v4.2, sealed; 3.5 kW load, 49 C ambient, 8 h required): complete. 10.0 h of silent watch, 6 C margin. Pass.",
|
||||
"A2": "RUN_THERMAL_SWEEP_0007 (thermal model v4.2, sealed; 3.5 kW load, 49 C ambient, 8 h required): complete. 8.1 h of silent watch, 3 C margin. Pass.",
|
||||
"A3": "RUN_THERMAL_SWEEP_0007 (thermal model v4.2, sealed; 3.5 kW load, 49 C ambient, 8 h required): complete. 24.0 h of silent watch, 9 C margin. Pass."
|
||||
},
|
||||
"techdata": {
|
||||
"bulletin": "TSB-22",
|
||||
"revision": "A",
|
||||
"component": "A2 battery-only pack, 46 kWh",
|
||||
"silent_watch_h_end_of_life": 8.1,
|
||||
"capacity_fade_pct": 0,
|
||||
"mtbf_h": 6000,
|
||||
"mttr_h": 3,
|
||||
"basis": "supplier qualification data, consistent with RUN_THERMAL_SWEEP_0007",
|
||||
"review": "complete"
|
||||
},
|
||||
"bom": {
|
||||
"baseline": "R2026.08",
|
||||
"A1": {
|
||||
"mass_lb": 380,
|
||||
"unit_cost_kusd": 145
|
||||
},
|
||||
"A2": {
|
||||
"mass_lb": 920,
|
||||
"integration_kusd": 61,
|
||||
"pack_kwh": 46,
|
||||
"usd_per_kwh": 520
|
||||
},
|
||||
"A3": {
|
||||
"mass_lb": 1450,
|
||||
"unit_cost_kusd": 38,
|
||||
"note": "towed"
|
||||
}
|
||||
},
|
||||
"base": "allow"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"model": "kai",
|
||||
"state": {
|
||||
"charter": {
|
||||
"decision": "DEC-SPH-0412",
|
||||
"need": "Select the auxiliary power source for the vehicle concept: at least 8 hours of silent watch at 3.5 kW and 49 C ambient, with the lowest field-maintenance burden at acceptable cost and mass.",
|
||||
"options": {
|
||||
"A1": "integrated APU",
|
||||
"A2": "battery-only pack, 46 kWh",
|
||||
"A3": "trailer genset"
|
||||
},
|
||||
"gate": "Before the concept gate every option needs a completed thermal qualification run and a reliability review of its current technical data."
|
||||
},
|
||||
"thermal": {
|
||||
"A1": "RUN_THERMAL_SWEEP_0007 (thermal model v4.2, sealed; 3.5 kW load, 49 C ambient, 8 h required): complete. 10.0 h of silent watch, 6 C margin. Pass.",
|
||||
"A2": "RUN_THERMAL_SWEEP_0007 (thermal model v4.2, sealed; 3.5 kW load, 49 C ambient, 8 h required): complete. 8.1 h of silent watch, 3 C margin. Pass.",
|
||||
"A3": "RUN_THERMAL_SWEEP_0007 (thermal model v4.2, sealed; 3.5 kW load, 49 C ambient, 8 h required): complete. 24.0 h of silent watch, 9 C margin. Pass."
|
||||
},
|
||||
"techdata": {
|
||||
"bulletin": "TSB-22",
|
||||
"revision": "A",
|
||||
"component": "A2 battery-only pack, 46 kWh",
|
||||
"silent_watch_h_end_of_life": 8.1,
|
||||
"capacity_fade_pct": 0,
|
||||
"mtbf_h": 6000,
|
||||
"mttr_h": 3,
|
||||
"basis": "supplier qualification data, consistent with RUN_THERMAL_SWEEP_0007",
|
||||
"review": "complete"
|
||||
},
|
||||
"bom": {
|
||||
"baseline": "R2026.08",
|
||||
"A1": {
|
||||
"mass_lb": 380,
|
||||
"unit_cost_kusd": 145
|
||||
},
|
||||
"A2": {
|
||||
"mass_lb": 920,
|
||||
"integration_kusd": 61,
|
||||
"pack_kwh": 46,
|
||||
"usd_per_kwh": 520
|
||||
},
|
||||
"A3": {
|
||||
"mass_lb": 1450,
|
||||
"unit_cost_kusd": 38,
|
||||
"note": "towed"
|
||||
}
|
||||
}
|
||||
},
|
||||
"questions": {
|
||||
"missing": {
|
||||
"type": "noul",
|
||||
"instructions": "Is a test result or review that the charter requires missing for any option?"
|
||||
},
|
||||
"conflict": {
|
||||
"type": "noul",
|
||||
"instructions": "Does the technical data disagree with the thermal qualification result?"
|
||||
},
|
||||
"best": {
|
||||
"type": "choice",
|
||||
"instructions": "Which option best meets the charter: at least 8 hours of silent watch with the lowest field-maintenance burden?",
|
||||
"criteria": {
|
||||
"A1": "integrated APU",
|
||||
"A2": "battery-only pack",
|
||||
"A3": "trailer genset"
|
||||
}
|
||||
},
|
||||
"anchor": {
|
||||
"type": "noul",
|
||||
"instructions": "Does the charter favor one option before the options were measured?"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"release": {
|
||||
"source": "O2",
|
||||
"claim": "fuel economy improved by more than 20%"
|
||||
},
|
||||
"status": {
|
||||
"diesel": "LTV::Diesel: Fielded JLTV powertrain: Gale Banks Engineering 866T V8 turbodiesel, based on the GM Duramax L5P, and an Allison 2500SP automatic (W1).",
|
||||
"hybrid": "LTV::Hybrid (since 2022-01-25, O2): Diesel-electric hybrid eJLTV. LTV::maturity: The eJLTV was a demonstrator with no orders when unveiled (B1)."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,350 @@
|
||||
// Light tactical vehicle powertrain trade: the fielded diesel JLTV against the diesel-electric
|
||||
// hybrid eJLTV. Every figure is from a public source, cited on its line by key:
|
||||
// W1 Wikipedia, "Joint Light Tactical Vehicle", retrieved 2026-09-25
|
||||
// W2 Wikipedia, "Humvee replacement process", retrieved 2026-09-25
|
||||
// O1 Oshkosh Defense, "JLTV & eJLTV" product page, retrieved 2026-09-25
|
||||
// O2 Oshkosh Defense, "Oshkosh Defense unveils first-ever silent drive hybrid electric JLTV", 2022-01-25
|
||||
// B1 Breaking Defense, "Oshkosh Defense announces first hybrid electric JLTV", 2022-01-25
|
||||
// D1 Defense News, "Oshkosh unveils hybrid electric Joint Light Tactical Vehicle", 2022-01-25
|
||||
// J1 Janes, "Oshkosh Defense builds hybrid-electric JLTV demonstrator", 2022-01-26
|
||||
// C1 CRS RS22942, "Joint Light Tactical Vehicle (JLTV): Background and Issues for Congress", 2020-02-18
|
||||
// C2 CRS IF11729, "Joint Light Tactical Vehicle (JLTV)", 2025-05-19
|
||||
// The evidence items at the end carry each source's URI.
|
||||
|
||||
package LTV {
|
||||
doc /* Powertrain trade for a light tactical vehicle of the JLTV class: keep the fielded
|
||||
diesel, or adopt the diesel-electric hybrid. */
|
||||
|
||||
private import ScalarValues::*;
|
||||
private import ISQ::*;
|
||||
private import SI::*;
|
||||
private import USCustomaryUnits::*;
|
||||
|
||||
// Tags: the graph reads a tag as a kind (demo/ontology.json adds ground-vehicle classes),
|
||||
// a relation, or a validity interval.
|
||||
metadata def Vendor;
|
||||
metadata def Evidence;
|
||||
metadata def Risk;
|
||||
metadata def Decision;
|
||||
metadata def Assumption;
|
||||
metadata def Supplies;
|
||||
metadata def Supports;
|
||||
metadata def Contradicts;
|
||||
metadata def Threatens;
|
||||
metadata def Supersedes;
|
||||
metadata def Validity {
|
||||
attribute since : String;
|
||||
attribute until : String;
|
||||
}
|
||||
|
||||
// Structure.
|
||||
|
||||
port def Shaft {
|
||||
doc /* Mechanical drive: torque out of the powertrain into the axles. */
|
||||
}
|
||||
port def Outlet {
|
||||
doc /* Electrical export power for mission equipment. */
|
||||
}
|
||||
|
||||
interface def Driveline {
|
||||
end port source : Shaft;
|
||||
end port sink : ~Shaft;
|
||||
}
|
||||
interface def Bus {
|
||||
end port source : Outlet;
|
||||
end port sink : ~Outlet;
|
||||
}
|
||||
|
||||
part def Engine;
|
||||
part def Transmission;
|
||||
part def Battery {
|
||||
attribute energy : EnergyValue;
|
||||
}
|
||||
part def Axle {
|
||||
port input : ~Shaft;
|
||||
}
|
||||
part def Equipment {
|
||||
doc /* Mission equipment that draws export power: radios, sensors, command post. */
|
||||
port inlet : ~Outlet;
|
||||
}
|
||||
|
||||
part def Powertrain {
|
||||
doc /* Engine, transmission and any electric drive: moves the vehicle and powers its
|
||||
mission equipment. */
|
||||
port shaft : Shaft;
|
||||
port outlet : Outlet;
|
||||
attribute power : PowerValue; // rated engine power
|
||||
attribute torque : TorqueValue; // peak engine torque
|
||||
attribute export : PowerValue; // export electrical power
|
||||
attribute silent : DurationValue; // silent drive endurance
|
||||
attribute economy : Real; // fuel economy gain over the fielded diesel, percent
|
||||
}
|
||||
|
||||
part def Diesel :> Powertrain {
|
||||
doc /* Fielded JLTV powertrain: Gale Banks Engineering 866T V8 turbodiesel, based on the
|
||||
GM Duramax L5P, and an Allison 2500SP automatic (W1). */
|
||||
part engine : Engine {
|
||||
attribute displacement = 6.6 [L]; // W1: 6.6 L Gale Banks Engineering 866T V8
|
||||
}
|
||||
part transmission : Transmission {
|
||||
attribute gears = 6; // W1: Allison 2500SP 6-speed automatic
|
||||
}
|
||||
attribute :>> power = 400 [hp]; // W1: 400 hp (298 kW)
|
||||
attribute :>> torque = 850 [lbf*ft]; // W1: 850 lb-ft (1,152 N-m)
|
||||
}
|
||||
|
||||
part def Hybrid :> Powertrain {
|
||||
@Validity { since = "2022-01-25"; } // O2: unveiled 2022-01-25
|
||||
doc /* Diesel-electric hybrid eJLTV: a lithium-ion battery the diesel recharges while
|
||||
driving, for silent drive, silent watch and export power without a towed
|
||||
generator. */
|
||||
part engine : Engine;
|
||||
part battery : Battery {
|
||||
attribute :>> energy = 30 [kW*h]; // O2: battery capacity of 30 kWh
|
||||
attribute life = 10 [yr]; // D1: designed for a minimum of 10 years
|
||||
}
|
||||
attribute :>> export = 115 [kW]; // O2: export power capacity of up to 115 kW
|
||||
attribute :>> silent = 30 [min]; // B1: 30 minutes of silent drive
|
||||
attribute :>> economy = 20; // O2: fuel economy improved by more than 20%
|
||||
attribute recharge = 30 [min]; // O2: fully recharges the battery within 30 minutes
|
||||
attribute added = 1000 [lb]; // J1: adds more than 1,000 lb to curb weight
|
||||
}
|
||||
|
||||
part def Vehicle {
|
||||
doc /* A light tactical vehicle: the powertrain drives the axles and powers mission
|
||||
equipment. */
|
||||
attribute curb : MassValue; // curb weight
|
||||
attribute gross : MassValue; // gross vehicle weight
|
||||
attribute payload : MassValue;
|
||||
attribute range : LengthValue;
|
||||
attribute speed : SpeedValue;
|
||||
attribute mmbomf : LengthValue; // mean miles between operational mission failure
|
||||
attribute cost : Real; // unit cost, USD
|
||||
part powertrain : Powertrain;
|
||||
part axles : Axle [2];
|
||||
part equipment : Equipment;
|
||||
interface drive : Driveline connect powertrain.shaft to axles.input;
|
||||
interface feed : Bus connect powertrain.outlet to equipment.inlet;
|
||||
}
|
||||
|
||||
part vehicle : Vehicle {
|
||||
doc /* The fielded four-door JLTV general purpose vehicle: curb and gross vehicle weight
|
||||
(GVW), payload, range, road speed, reliability and unit cost. */
|
||||
part :>> powertrain : Diesel;
|
||||
attribute :>> curb = 14000 [lb]; // W1: curb weight 14,000 lb
|
||||
attribute :>> gross = 22500 [lb]; // W1: gross weight 22,500 lb
|
||||
attribute :>> payload = 3500 [lb]; // O1: 4-door payload 3,500 lb
|
||||
attribute :>> range = 300 [mi]; // W1: range 300 mi
|
||||
attribute :>> speed = 70 [mi/h]; // W1: 70 mph on road
|
||||
attribute :>> mmbomf = 7051 [mi]; // W2: Oshkosh EMD vehicles, 7,051 MMBOMF
|
||||
attribute :>> cost = 370000; // W1: unit cost $370,000-399,000 (low end)
|
||||
}
|
||||
|
||||
// Requirements.
|
||||
|
||||
requirement <'R1'> payload {
|
||||
doc /* Carry the four-door general purpose payload. */
|
||||
subject vehicle : Vehicle;
|
||||
attribute required = 3500 [lb]; // O1: 4-door payload 3,500 lb
|
||||
require constraint { vehicle.payload >= required }
|
||||
}
|
||||
requirement <'R2'> reliability {
|
||||
doc /* Mean miles between operational mission failure (MMBOMF) at or above the JLTV
|
||||
target. */
|
||||
subject vehicle : Vehicle;
|
||||
attribute required = 2400 [mi]; // W2: the target for JLTV is 2,400 MMBOMF
|
||||
require constraint { vehicle.mmbomf >= required }
|
||||
}
|
||||
requirement <'R3'> range {
|
||||
doc /* Operating range on internal fuel. */
|
||||
subject vehicle : Vehicle;
|
||||
attribute required = 300 [mi]; // W1: range 300 mi
|
||||
require constraint { vehicle.range >= required }
|
||||
}
|
||||
requirement <'R4'> transport {
|
||||
doc /* Air transportable: sling-loaded by CH-47 and CH-53 helicopters, carried by C-130
|
||||
aircraft (O1). */
|
||||
subject vehicle : Vehicle;
|
||||
assume constraint unchanged {
|
||||
doc /* The hybrid keeps the JLTV's dimensions and transportability, as Oshkosh
|
||||
states (J1). */
|
||||
}
|
||||
}
|
||||
requirement <'R5'> power {
|
||||
doc /* Power mission equipment on board, without a towed generator. */
|
||||
subject vehicle : Vehicle;
|
||||
}
|
||||
requirement <'R6'> stealth {
|
||||
doc /* Silent drive and silent watch: move and hold position on battery with the engine
|
||||
off. */
|
||||
subject vehicle : Vehicle;
|
||||
}
|
||||
|
||||
// The decision and its alternatives.
|
||||
|
||||
#Decision analysis trade {
|
||||
doc /* Choose the powertrain for the light tactical vehicle: keep the fielded diesel or
|
||||
adopt the diesel-electric hybrid. */
|
||||
subject vehicle : Vehicle;
|
||||
part diesel : Diesel;
|
||||
part hybrid : Hybrid;
|
||||
}
|
||||
|
||||
satisfy payload by trade.diesel;
|
||||
satisfy reliability by trade.diesel;
|
||||
satisfy range by trade.diesel;
|
||||
satisfy transport by trade.diesel;
|
||||
satisfy range by trade.hybrid;
|
||||
satisfy transport by trade.hybrid;
|
||||
satisfy power by trade.hybrid;
|
||||
satisfy stealth by trade.hybrid;
|
||||
|
||||
// Verification.
|
||||
|
||||
verification weighing {
|
||||
doc /* Weigh at curb and gross vehicle weight; load to rated payload. */
|
||||
subject vehicle : Vehicle;
|
||||
objective { verify payload; }
|
||||
}
|
||||
verification airlift {
|
||||
doc /* Sling-load certification under CH-47 and CH-53; C-130 load planning. */
|
||||
subject vehicle : Vehicle;
|
||||
objective { verify transport; }
|
||||
}
|
||||
verification durability {
|
||||
doc /* Reliability, availability and maintainability miles: score mission failures to
|
||||
compute MMBOMF; measure range on internal fuel. */
|
||||
subject vehicle : Vehicle;
|
||||
objective {
|
||||
verify reliability;
|
||||
verify range;
|
||||
}
|
||||
}
|
||||
verification bench {
|
||||
doc /* Load-bank export power; silent watch and silent drive on battery with the engine
|
||||
off. */
|
||||
subject vehicle : Vehicle;
|
||||
objective {
|
||||
verify power;
|
||||
verify stealth;
|
||||
}
|
||||
}
|
||||
|
||||
// Vendors.
|
||||
|
||||
#Vendor part oshkosh {
|
||||
doc /* Oshkosh Defense: JLTV producer from the 2015 award (W1); developer of the eJLTV (O2). */
|
||||
}
|
||||
#Vendor part amgeneral {
|
||||
doc /* AM General: JLTV follow-on producer from February 2023 (C2). */
|
||||
}
|
||||
#Vendor part banks {
|
||||
doc /* Gale Banks Engineering: the 866T V8 turbodiesel (W1). */
|
||||
}
|
||||
#Vendor part allison {
|
||||
doc /* Allison Transmission: the 2500SP automatic (W1). */
|
||||
}
|
||||
|
||||
#Supplies dependency from oshkosh to Diesel {
|
||||
@Validity { since = "2015-08-25"; until = "2023-02-09"; } // W1: awarded 2015-08-25; C2: follow-on awarded 2023-02-09
|
||||
}
|
||||
#Supplies dependency from oshkosh to Hybrid;
|
||||
#Supplies dependency from amgeneral to Diesel {
|
||||
@Validity { since = "2023-02-09"; } // C2: follow-on awarded 2023-02-09
|
||||
}
|
||||
#Supplies dependency from banks to Diesel::engine;
|
||||
#Supplies dependency from allison to Diesel::transmission;
|
||||
|
||||
// Risks and assumptions.
|
||||
|
||||
#Risk concern weight {
|
||||
doc /* The hybrid adds more than 1,000 lb of curb weight (J1): at the same gross vehicle
|
||||
weight it costs payload, and it narrows helicopter lift margin. */
|
||||
}
|
||||
#Risk concern maturity {
|
||||
doc /* The eJLTV was a demonstrator with no orders when unveiled (B1). */
|
||||
}
|
||||
#Risk concern procurement {
|
||||
@Validity { since = "2025-05-01"; } // C2: Army Transformation Initiative letter, 2025-05-01
|
||||
doc /* The Army ended JLTV procurement after its January 2025 tranche (C2). */
|
||||
}
|
||||
|
||||
#Threatens dependency from weight to payload;
|
||||
#Threatens dependency from weight to transport;
|
||||
#Threatens dependency from weight to trade.hybrid;
|
||||
#Threatens dependency from maturity to trade.hybrid;
|
||||
#Threatens dependency from procurement to trade;
|
||||
|
||||
#Assumption constraint cycle {
|
||||
doc /* The fuel economy gain of more than 20% (O2) holds over the Army duty cycle: a
|
||||
company figure, not an Army test result. */
|
||||
}
|
||||
#Supports dependency from cycle to trade.hybrid;
|
||||
|
||||
// Evidence.
|
||||
|
||||
#Evidence item <'W1'> wikipedia {
|
||||
doc /* Wikipedia, "Joint Light Tactical Vehicle": engine, power, torque, weights, range,
|
||||
speed, unit cost and contract awards. */
|
||||
attribute uri = "https://en.wikipedia.org/wiki/Joint_Light_Tactical_Vehicle";
|
||||
}
|
||||
#Evidence item <'W2'> replacement {
|
||||
doc /* Wikipedia, "Humvee replacement process": reliability of the EMD vehicles against
|
||||
the JLTV target, in MMBOMF. */
|
||||
attribute uri = "https://en.wikipedia.org/wiki/Humvee_replacement_process";
|
||||
}
|
||||
#Evidence item <'O1'> product {
|
||||
doc /* Oshkosh Defense, "JLTV & eJLTV": payload by door count and air transportability. */
|
||||
attribute uri = "https://oshkoshdefense.com/vehicles/light-tactical-vehicles/jltv/";
|
||||
}
|
||||
#Evidence item <'O2'> release {
|
||||
@Validity { since = "2022-01-25"; }
|
||||
doc /* Oshkosh Defense press release unveiling the eJLTV: battery, recharge, fuel economy
|
||||
and export power. */
|
||||
attribute uri = "https://oshkoshdefense.com/oshkosh-defense-unveils-first-ever-silent-drive-hybrid-electric-jltv/";
|
||||
}
|
||||
#Evidence item <'B1'> breaking {
|
||||
@Validity { since = "2022-01-25"; }
|
||||
doc /* Breaking Defense on the eJLTV: silent drive endurance; no orders at unveiling. */
|
||||
attribute uri = "https://breakingdefense.com/2022/01/oshkosh-defense-announces-first-hybrid-electric-jltv/";
|
||||
}
|
||||
#Evidence item <'D1'> news {
|
||||
@Validity { since = "2022-01-25"; }
|
||||
doc /* Defense News on the eJLTV: battery capacity and design life, export power. */
|
||||
attribute uri = "https://www.defensenews.com/land/2022/01/25/oshkosh-unveils-hybrid-electric-joint-light-tactical-vehicle/";
|
||||
}
|
||||
#Evidence item <'J1'> janes {
|
||||
@Validity { since = "2022-01-26"; }
|
||||
doc /* Janes on the eJLTV demonstrator: added curb weight; dimensions and
|
||||
transportability unchanged. */
|
||||
attribute uri = "https://www.janes.com/osint-insights/defence-news/land/oshkosh-defense-builds-hybrid-electric-jltv-demonstrator";
|
||||
}
|
||||
#Evidence item <'C1'> background {
|
||||
@Validity { since = "2020-02-18"; }
|
||||
doc /* CRS RS22942, quoting DOT&E's FY2018 report: all JLTVs are not operationally
|
||||
suitable because of deficiencies in reliability, maintainability, training,
|
||||
manuals, crew situational awareness and safety. */
|
||||
attribute uri = "https://www.everycrsreport.com/files/20200218_RS22942_9231b713562f5293806d3868ef892cbc6c6798c5.html";
|
||||
}
|
||||
#Evidence item <'C2'> status {
|
||||
@Validity { since = "2025-05-19"; }
|
||||
doc /* CRS IF11729: AM General follow-on award; the Army ends JLTV procurement. */
|
||||
attribute uri = "https://www.everycrsreport.com/files/2025-05-19_IF11729_b3d5f3f3f68c2c1d061e8befe0d0261fe8e4cbd3.html";
|
||||
}
|
||||
|
||||
#Supports dependency from wikipedia to Diesel;
|
||||
#Supports dependency from wikipedia to vehicle;
|
||||
#Supports dependency from wikipedia to range;
|
||||
#Supports dependency from replacement to reliability;
|
||||
#Supports dependency from replacement to trade.diesel;
|
||||
#Supports dependency from product to payload;
|
||||
#Supports dependency from product to transport;
|
||||
#Supports dependency from release to Hybrid;
|
||||
#Supports dependency from breaking to Hybrid;
|
||||
#Supports dependency from news to Hybrid;
|
||||
#Supports dependency from janes to weight;
|
||||
#Supports dependency from janes to transport::unchanged;
|
||||
#Supports dependency from status to procurement;
|
||||
#Contradicts dependency from background to trade.diesel;
|
||||
#Supersedes dependency from status to background;
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
{
|
||||
"id": "ltv.trade",
|
||||
"version": 1,
|
||||
"description": "Powertrain trade for a light tactical vehicle of the JLTV class, over the cited model demo/ltv.sysml: the fielded diesel against the eJLTV hybrid. Hybrid figures are the model's (source keys in its header); the diesel is the baseline they are measured from, so its gains are 0. Requirement attributes are 1 where the model records `satisfy <requirement> by trade.<option>`. Weights are an analyst's example.",
|
||||
"options": [
|
||||
{
|
||||
"id": "diesel",
|
||||
"label": "fielded diesel: 866T V8 turbodiesel, Allison 2500SP",
|
||||
"attributes": {
|
||||
"economy": 0,
|
||||
"added": 0,
|
||||
"silent": 0,
|
||||
"payload": 1,
|
||||
"reliability": 1,
|
||||
"transport": 1,
|
||||
"power": 0,
|
||||
"stealth": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hybrid",
|
||||
"label": "eJLTV diesel-electric hybrid",
|
||||
"attributes": {
|
||||
"economy": 20,
|
||||
"added": 1000,
|
||||
"silent": 30,
|
||||
"payload": 0,
|
||||
"reliability": 0,
|
||||
"transport": 1,
|
||||
"power": 1,
|
||||
"stealth": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"metrics": [
|
||||
{
|
||||
"id": "fuel",
|
||||
"node": "fuel",
|
||||
"unit": "%",
|
||||
"description": "fuel economy gain over the fielded diesel that holds on the duty cycle (O2)"
|
||||
},
|
||||
{
|
||||
"id": "weight",
|
||||
"node": "weight",
|
||||
"unit": "lb",
|
||||
"description": "curb weight added (J1)"
|
||||
},
|
||||
{
|
||||
"id": "field",
|
||||
"node": "field",
|
||||
"description": "R5 export power and R6 silent drive and watch, satisfied"
|
||||
},
|
||||
{
|
||||
"id": "proven",
|
||||
"node": "proven",
|
||||
"description": "R1 payload and R2 reliability, satisfied"
|
||||
},
|
||||
{
|
||||
"id": "lift",
|
||||
"node": "lift",
|
||||
"description": "R4 air transport, satisfied"
|
||||
},
|
||||
{
|
||||
"id": "mature",
|
||||
"node": "mature",
|
||||
"description": "P(fielded and in production)"
|
||||
}
|
||||
],
|
||||
"objectives": [
|
||||
{
|
||||
"id": "economy",
|
||||
"metric": "fuel",
|
||||
"weight": 0.2,
|
||||
"direction": "max"
|
||||
},
|
||||
{
|
||||
"id": "mass",
|
||||
"metric": "weight",
|
||||
"weight": 0.2,
|
||||
"direction": "min"
|
||||
},
|
||||
{
|
||||
"id": "capability",
|
||||
"metric": "field",
|
||||
"weight": 0.2,
|
||||
"direction": "max"
|
||||
},
|
||||
{
|
||||
"id": "record",
|
||||
"metric": "proven",
|
||||
"weight": 0.2,
|
||||
"direction": "max"
|
||||
},
|
||||
{
|
||||
"id": "maturity",
|
||||
"metric": "mature",
|
||||
"weight": 0.2,
|
||||
"direction": "max"
|
||||
}
|
||||
],
|
||||
"constraints": [
|
||||
{
|
||||
"id": "airlift",
|
||||
"metric": "lift",
|
||||
"op": ">=",
|
||||
"bound": 1
|
||||
}
|
||||
],
|
||||
"assumptions": [
|
||||
{
|
||||
"id": "cycle",
|
||||
"value": 1,
|
||||
"range": [
|
||||
0,
|
||||
1
|
||||
],
|
||||
"confidence": 0.5,
|
||||
"evidence": "release",
|
||||
"description": "The share of the hybrid's >20% fuel economy gain (O2, a company figure, not an Army test) that holds on the Army duty cycle. Confidence is the analyst's."
|
||||
}
|
||||
],
|
||||
"bias": [
|
||||
{
|
||||
"id": "anchoring",
|
||||
"check": "Was the fielded diesel treated as the answer before the options were measured?",
|
||||
"node": "anchor"
|
||||
}
|
||||
],
|
||||
"evidence": [
|
||||
{
|
||||
"id": "model",
|
||||
"uri": "file:ltv.sysml",
|
||||
"description": "the cited SysML v2 model"
|
||||
},
|
||||
{
|
||||
"id": "release",
|
||||
"uri": "https://oshkoshdefense.com/oshkosh-defense-unveils-first-ever-silent-drive-hybrid-electric-jltv/",
|
||||
"description": "O2, the source of the fuel economy figure"
|
||||
},
|
||||
{
|
||||
"id": "status",
|
||||
"uri": "sysml:LTV::Diesel,LTV::Hybrid,LTV::maturity",
|
||||
"description": "each option's status in the model, keyed by option: its definition's doc and the concerns that threaten it"
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "fuel",
|
||||
"kind": "expr",
|
||||
"inputs": [
|
||||
"cycle"
|
||||
],
|
||||
"expr": "economy * cycle"
|
||||
},
|
||||
{
|
||||
"id": "weight",
|
||||
"kind": "expr",
|
||||
"expr": "added"
|
||||
},
|
||||
{
|
||||
"id": "field",
|
||||
"kind": "expr",
|
||||
"expr": "power + stealth"
|
||||
},
|
||||
{
|
||||
"id": "proven",
|
||||
"kind": "expr",
|
||||
"expr": "payload + reliability"
|
||||
},
|
||||
{
|
||||
"id": "lift",
|
||||
"kind": "expr",
|
||||
"expr": "transport"
|
||||
},
|
||||
{
|
||||
"id": "mature",
|
||||
"kind": "kai",
|
||||
"inputs": [
|
||||
"status"
|
||||
],
|
||||
"model": "kai",
|
||||
"question": {
|
||||
"type": "noul",
|
||||
"instructions": "Is this powertrain fielded and in production, rather than a demonstrator?"
|
||||
},
|
||||
"scope": "option"
|
||||
},
|
||||
{
|
||||
"id": "brief",
|
||||
"kind": "zen",
|
||||
"inputs": [
|
||||
"model"
|
||||
],
|
||||
"prompt": "Summarize the trade for a decision brief. Cite the source key for every figure; add no figure the model does not hold."
|
||||
},
|
||||
{
|
||||
"id": "anchor",
|
||||
"kind": "kai",
|
||||
"inputs": [
|
||||
"brief"
|
||||
],
|
||||
"model": "kai",
|
||||
"question": {
|
||||
"type": "noul",
|
||||
"instructions": "Does the brief treat the fielded diesel as the answer before weighing the options?"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "approve",
|
||||
"kind": "human",
|
||||
"inputs": [
|
||||
"fuel",
|
||||
"mature"
|
||||
],
|
||||
"role": "program manager"
|
||||
}
|
||||
],
|
||||
"refresh": {
|
||||
"on": [
|
||||
"model"
|
||||
]
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
+54
@@ -0,0 +1,54 @@
|
||||
"""Ask Kai every question of an Army demonstration program on api.hanzo.ai, as the program runtime
|
||||
asks them, and print each answer beside the one recorded in recorded.json.
|
||||
|
||||
HANZO_API_KEY=... python3 army/run.py apu # or jltv
|
||||
|
||||
A program-scope question reads its inputs; an option-scope question is asked once per option,
|
||||
with the option and, for an input keyed by option id, that option's entry alone.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
URL = os.environ.get("KAI_URL", "https://api.hanzo.ai") + "/v1/decisions"
|
||||
here = Path(__file__).parent / sys.argv[1]
|
||||
program = json.loads(next(here.glob("*@*.json")).read_text())
|
||||
evidence = json.loads((here / "evidence.json").read_text())
|
||||
for e in program["evidence"]:
|
||||
if e["uri"].startswith("file:"):
|
||||
evidence[e["id"]] = (here / e["uri"][5:]).read_text()
|
||||
recorded = json.loads((here / "recorded.json").read_text())[0]["package"]["results"]
|
||||
options = program.get("options", [])
|
||||
|
||||
|
||||
def ask(question, state):
|
||||
body = json.dumps({"model": "kai", "state": state, "questions": {"q": question}}).encode()
|
||||
req = urllib.request.Request(URL, data=body, headers={
|
||||
"content-type": "application/json", "authorization": f"Bearer {os.environ['HANZO_API_KEY']}"})
|
||||
with urllib.request.urlopen(req, timeout=120) as r:
|
||||
a = json.load(r)["answers"]["q"]
|
||||
return {"false": 1 - a["noul"], "true": a["noul"]} if "noul" in a else a["probabilities"]
|
||||
|
||||
|
||||
def top(d):
|
||||
k = max(d, key=d.get)
|
||||
return f"{k} {d[k]:.3f}"
|
||||
|
||||
|
||||
for node in program["nodes"]:
|
||||
if node["kind"] != "kai":
|
||||
continue
|
||||
inputs = {i: evidence[i] if i in evidence else recorded[i]["output"] for i in node["inputs"]}
|
||||
if node.get("scope") == "option":
|
||||
for o in options:
|
||||
state = {i: (v[o["id"]] if isinstance(v, dict) and all(p["id"] in v for p in options) else v)
|
||||
for i, v in inputs.items()}
|
||||
state["option"] = o
|
||||
got = ask(node["question"], state)
|
||||
print(f"{node['id']}[{o['id']}]: {top(got)} (recorded {top(recorded[node['id']]['output'][o['id']])})")
|
||||
else:
|
||||
state = next(iter(inputs.values())) if len(inputs) == 1 else inputs
|
||||
got = ask(node["question"], state)
|
||||
print(f"{node['id']}: {top(got)} (recorded {top(recorded[node['id']]['output'])})")
|
||||
Reference in New Issue
Block a user