Lattice Grid Buy a licence

demo D292

Summarise delivery risk in one line

Turn a project plan and a board into the one line a delivery lead wants: how many tasks are at risk on the critical path, how the schedule and cost are tracking, and how many service limits have slipped, each figure computed by the plan and the board and reconciled so no number is invented, with task names and money held back unless you opt in

createAI · ai.riskSummary(sources)

This turns a project plan and a board into the one line a delivery lead wants to read: how many tasks are at risk on the critical path, how the schedule and cost are tracking, and how many service limits have slipped. Every figure is computed by the plan and the board, then reconciled so a number the model did not ground is stripped before you see it.

Building…
Loading a live grid…

The configuration

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.47.0/lattice-grid.min.css">
<script src="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.47.0/lattice-grid.min.js"></script>

<div id="summary"></div>

<script type="module">
  import { createAI } from '@toclocoinc/lattice-grid/modules/ai';
  // The Gantt and Kanban modules are separate; the AI bundle imports neither.
  // You pass their already-computed outputs, and the layer reads them duck-typed.

  // The plan and the board have already done the maths. The schedule reports its
  // critical path and the tasks on it; earned value reports the schedule (SPI)
  // and cost (CPI) indices; the board reports its own SLA breach and warning
  // counts. None of this is asked of the model.
  const schedule = gantt.schedule;
  const earnedValue = gantt.earnedValue({ statusDate });
  const breaches = board.sla.breaches();
  const warnings = board.sla.warnings();

  // Your model, your key, your network call. The module makes none: it hands
  // ask() only the aggregate figures above and validates the text that comes
  // back. Swap this body for a call to the provider of your choice.
  const ask = async ({ system, messages, message }) => {
    const reply = await myProvider.chat({ system, messages });
    return { text: reply.text };
  };

  const ai = createAI(headlessGrid, { ask, tools: false });

  // One grounded line: "3 tasks at risk on the critical path, SPI 0.66, 2 SLA
  // breaches." Every figure is reconciled against the computed values above, so
  // a number the modules did not produce is stripped before it is shown. By
  // default the summary carries aggregates only; includeTaskNames and
  // includeCost each add more, reported back in meta.exposed.
  const { text, meta } = await ai.riskSummary({ schedule, earnedValue, breaches, warnings });
  document.getElementById('summary').textContent = text;
</script>

The status update, without the status meeting

A plan and a board hold everything you need to know whether delivery is on track, but reading it means opening two tools and doing the arithmetic in your head. This writes the summary instead: one plain line that leads with the tasks still open on the critical path, the schedule and cost performance, and the service limits that have already slipped. It is the sentence a delivery lead would say out loud, produced from the numbers rather than a feeling about them.

The point is where the numbers come from. The plan is scheduled by the project module, which reports its critical path and its earned-value indices; the board is aged by the board module, which reports its own breach and warning counts. Those computed outputs are the ground the summary must stand on. Every figure in the line is checked back against them, so a number that was not computed is removed before it reaches you. The model writes the sentence; it does not invent the arithmetic.

Trust is the default, not a setting. A summary carries aggregates only unless you say otherwise: the counts and the indices, never a task name or a money figure. When the audience is right for more, you add the at-risk task names or the cost figures on purpose, and the summary reports exactly what it exposed.

How do I summarise delivery risk?

Hand the AI layer the outputs the plan and the board have already produced: the schedule, the earned value for a status date, and the board’s breach and warning lists. Call ai.riskSummary({ schedule, earnedValue, breaches, warnings }), or the { kind: 'risk' } target of explain, and you get the grounded line back. Your own model, wrapped in ask, writes the words; the grid holds no key and makes no call of its own, and hands the model only the aggregate figures. To widen what the summary may say, pass includeTaskNames or includeCost, each reported back in meta.exposed so the exposure is never silent.