· ENPT-BR
Grok Build for Alembic · Integration mechanics

Headless JSONL: reconstruct the answer honestly

Follow thought, text, end, and error events without inventing a final-result event.

Primary source
Pinned headless mode guide

Pinned upstream commit: b189869b7755d2b482969acf6c92da3ecfeffd36

The Simple layer stands alone; open Technical for exact contracts and edge cases.
You will be able to
  • Reconstruct an answer from ordered text deltas.
  • Read `end` as metadata, not answer text.
  • Explain why unknown events are ignored and process failure still fails.
1

The big idea


In streaming mode Grok prints one JSON object per line. Text arrives in pieces, so Alembic appends each `data` field in order. The final `end` line closes the stream and carries the session and usage metadata; it does not repeat the answer. Unknown lines are ignored so a future event does not corrupt today's result.

Think of it like… It is a train: each `text` line is a carriage carrying part of the answer, while `end` is the guard's lantern confirming the train is complete. The lantern carries paperwork, not another carriage. The analogy breaks because JSONL can include ignorable event types between text chunks.

`parseStreamLine` is stateless: `text` becomes a parsed text event; `end` may become session and usage events; `error` becomes a result/error detail; thought, unknown, malformed, and non-JSON lines produce no events. State lives in Orchestrator's ordered accumulator.

The result fallback is `resultText || accumulatedOutput || raw stdout`. That order matters: Grok's normal stream has deltas plus metadata-only end, so accumulated text must beat raw JSONL. A non-zero process exit still fails the run and prefers stderr for diagnosis.

Evidence: Pinned headless mode guide

stdinprocessJSONLthoughttext-1 Safe: append only `text.data`, then return the accumulator.
Follow thought, text, end, and error events without inventing a final-result event.
2

Compare the boundaries


Safe
Safe: append only `text.data`, then return the accumulator.
Risky
Risky: serialize `end` or raw JSONL as the assistant answer.
SurfaceUpstreamAlembicVerdict
text`data` answer deltaAppend to accumulatorKEEP
thoughtReasoning streamIgnore in provider outputIGNORE
endSession + usage metadataEmit metadata; no final textCLOSE

The result fallback is `resultText || accumulatedOutput || raw stdout`. That order matters: Grok's normal stream has deltas plus metadata-only end, so accumulated text must beat raw JSONL. A non-zero process exit still fails the run and prefers stderr for diagnosis.

3

Real code and commands


packages/factory/src/GrokAgentProvider.ts
if (event.type === "text" && typeof event.data === "string") {
  return [{ type: "text", text: event.data }];
}

if (event.type !== "end") return [];
if (typeof event.sessionId === "string") {
  parsed.push({ type: "session_id", sessionId: event.sessionId });
}
How to reach it
sed -n '35,120p' packages/factory/src/GrokAgentProvider.ts
sed -n '145,205p' packages/factory/src/Orchestrator.ts

Evidence: RESOURCES.md

4

Visual atlas


inputproofstdin
Trace the boundary: stdin.
surfaceseamownerprocess
Locate the owner: process.
claimwithout gateevidenceat boundaryvsJSONL
Compare claim and evidence: JSONL.
learnexecuteverifythought
Read the sequence: thought.
complete?yes / notext-1
Find the decision gate: text-1.
inputprooftext-2
Trace the boundary: text-2.
surfaceseamownerend
Locate the owner: end.
claimwithout gateevidenceat boundaryvssessionId
Compare claim and evidence: sessionId.
learnexecuteverifyusage
Read the sequence: usage.
complete?yes / noerror
Find the decision gate: error.
inputproofparser
Trace the boundary: parser.
surfaceseamowneraccumulator
Locate the owner: accumulator.
claimwithout gateevidenceat boundaryvsresult
Compare claim and evidence: result.
learnexecuteverifystderr
Read the sequence: stderr.
5

Practice and feedback


Predict before revealing

The stream emits two text deltas and then `end`. Where is the final answer?

In the ordered concatenation of the two deltas; `end` contributes metadata only.

Retrieval cards

Retrieval cardsJSONLClick or press Enter to flip
JSONLOne complete JSON object per line.
Retrieval cardsText deltaClick or press Enter to flip
Text deltaA partial answer chunk appended in order.
Retrieval cardsTerminal eventClick or press Enter to flip
Terminal eventThe final metadata event, always last.
Retrieval cardsAccumulatorClick or press Enter to flip
AccumulatorOrchestrator state that rebuilds the response.
In streaming mode Grok prints one JSON object per line. Text arrives in pieces, so Alembic appends each `data` field in order. The final `end` line closes the stream and carries the session and usage metadata; it does not repeat the answer. Unknown lines are ignored so a future event does not corrupt today's result.
`parseStreamLine` is stateless: `text` becomes a parsed text event; `end` may become session and usage events; `error` becomes a result/error detail; thought, unknown, malformed, and non-JSON lines produce no events. State lives in Orchestrator's ordered accumulator.

Step through the stream

Select an event and see the exact provider action.

Verdict

Four-slide summary

JSONL

One complete JSON object per line.

Text delta

A partial answer chunk appended in order.

Terminal event

The final metadata event, always last.

Accumulator

Orchestrator state that rebuilds the response.

Check your model

Spaced review

Which event supplies normal final answer text?

`text` carries deltas. `end` closes the stream and carries metadata.
6

Sources and next move


Ask your teacher to challenge a verdict, replay an event, or review a future unit against the same proof discipline.