Chapter 4: State: Feeding the Model the Right Context

Learning Objectives

Pre-Quiz: The Three Shapes of State

A NOC engineer wants to send the last twenty Aruba AOS-CX syslog lines from a stack member, oldest first, where the sequence of events determines the diagnosis. Which state shape fits best, and why?

A JSON object, because it lets each line have a descriptive field name
An array of text values, because the items are the same kind of thing and their order carries meaning
A single string with the lines joined by newlines, because it is simplest
An array of JSON objects with a timestamp field per line, since that is more structured

According to TypeSafe's guidance, why is a JSON object the recommended default shape for state, even for data that could technically be expressed as a string?

It compresses to fewer tokens than a string
Descriptive field names preserve meaning and make each part addressable by a question's path
Objects are the only shape a System One request accepts
Objects automatically strip transport metadata like jsonrpc envelopes

A field technician texts a photo of a fiber patch panel to a ticket. What is the correct way to make this information available as System One state?

Attach the image file directly as the state parameter, since JSON supports base64-encoded binary
Describe the photo in the question's instructions instead of putting it in state
Convert it to text first, since only strings, objects, and arrays of text are supported
Skip the photo and rely on the model's general knowledge of fiber patch panels

The Three Shapes of State

Key Points

In a System One request, state is the material the model looks at, and questions are the judgments you want made about it. The split is deliberate — like separating a routing table (data) from a route-map (policy applied to it). You do not stuff policy clauses into the prefix list.

Figure 4.1: The Three Shapes of State

graph TD State["State"] --> A["String"] State --> B["JSON Object"] State --> C["JSON Array"] A --> A1["Single Cisco syslog line: LINEPROTO-5-UPDOWN"] B --> B1["ServiceNow incident plus interface counters"] C --> C1["Last twenty Aruba AOS-CX syslog lines, oldest first"]
State shapeUse it whenNetwork exampleWhat questions can reference
StringOne self-contained piece of text and no other context mattersA single %LINEPROTO-5-UPDOWN lineThe text as a whole ("the message")
JSON objectSeveral related facts must be weighed together, each deserving a nameA ServiceNow incident plus interface counters and syslogNamed fields by path: incident.short_description
JSON arrayAn ordered sequence of same-kind items where position carries meaningLast twenty syslog lines, oldest firstPositional paths: [0], [-1]

String State

The simplest state is a plain string — reserved for genuinely single-piece inputs. The moment you catch yourself concatenating a ticket summary, a hostname, and counters into one newline-separated blob, you have outgrown the string shape: you have built an object with the field names deleted, and no question can point at any one part of it.

state = (
    "<189>Sep 17 14:02:11 dc1-acc-07 %LINEPROTO-5-UPDOWN: "
    "Line protocol on Interface GigabitEthernet1/0/24, changed state to down"
)

response = client.system_one(
    state=state,
    questions={"subsystem": Choice(instructions="Which network subsystem?", criteria={...})},
)

Object State

Object is the documented default: "Use an object for most requests so each part of the state has a descriptive name and its relationships remain clear." The field name is itself context — admin_down_by_change_ticket tells the model more than a bare true. Named fields are addressable, which is what makes path references possible. Grouping matters too: keep an incident and the telemetry that proves or disproves it in one object, because the judgment depends on their relationship.

{
  "incident": {"number": "INC0042771", "short_description": "Uplink flapping on dc1-core-a"},
  "device": {"hostname": "dc1-core-a", "platform": "Arista EOS", "role": "spine"},
  "interfaces": {"Ethernet1": {"lineProtocolStatus": "down", "linkStatusChanges": 214}}
}

Array State

Arrays fit "a sequence of messages or records" where items are the same kind of thing and order carries meaning — a syslog burst is the canonical case, since ordering often is the diagnosis. The constraint hiding in the spec: array state is an array of text values. If your records are themselves structured, put the array inside an object field instead — which also lets you label and pair it with related data.

[
  "13:50:02 dc1-core-a: Interface Ethernet1 changed state to down",
  "13:50:03 dc1-core-a: BGP peer 10.0.2.3 Down - interface flap"
]

Text-Only: No Images, Audio, or Video

"State must be a string, JSON object, or array of text values. Images, audio, and video are not supported (yet)." You cannot hand the model a NetFlow screenshot, a topology diagram, or a raw .pcap. The workaround: render it to text before it becomes state. A packet capture becomes tshark field output; a topology becomes an adjacency list {"dc1-core-a": ["dc1-leaf-01", "dc1-leaf-02"]}, which is more useful than the picture since it is already the data the picture was drawn from.

Key Takeaway: State comes in exactly three shapes — string, JSON object, and array of text values — and objects are the recommended default because descriptive field names preserve both meaning and addressability. Use a string only for a genuinely single passage, an array for ordered same-kind records, and convert any non-text artifact into text before it can become state.
Post-Quiz: The Three Shapes of State

A NOC engineer wants to send the last twenty Aruba AOS-CX syslog lines from a stack member, oldest first, where the sequence of events determines the diagnosis. Which state shape fits best, and why?

A JSON object, because it lets each line have a descriptive field name
An array of text values, because the items are the same kind of thing and their order carries meaning
A single string with the lines joined by newlines, because it is simplest
An array of JSON objects with a timestamp field per line, since that is more structured

According to TypeSafe's guidance, why is a JSON object the recommended default shape for state, even for data that could technically be expressed as a string?

It compresses to fewer tokens than a string
Descriptive field names preserve meaning and make each part addressable by a question's path
Objects are the only shape a System One request accepts
Objects automatically strip transport metadata like jsonrpc envelopes

A field technician texts a photo of a fiber patch panel to a ticket. What is the correct way to make this information available as System One state?

Attach the image file directly as the state parameter, since JSON supports base64-encoded binary
Describe the photo in the question's instructions instead of putting it in state
Convert it to text first, since only strings, objects, and arrays of text are supported
Skip the photo and rely on the model's general knowledge of fiber patch panels
Pre-Quiz: Building State from Network Sources

Both Arista eAPI and Cisco NX-API return show command output as structured JSON over JSON-RPC 2.0. What is the main practical difference an engineer must handle when building state from each?

eAPI requires OAuth while NX-API only supports basic auth
Cisco wraps its response in an ins_api envelope with TABLE/ROW entries, while Arista returns the data more directly
NX-API cannot run multiple commands in a single transaction, while eAPI can
eAPI returns XML while NX-API returns JSON

An engineer is deciding whether to keep a show interface block from an Aruba AOS-CX switch as raw text or parse it into named fields. Per the chapter's guidance, when should it stay raw text?

Always — raw text preserves the vendor's exact wording and is simpler to build
When a question needs to reference one specific value from it by path
When the output is short, self-describing, and no question needs to address a specific value by path
When the output is long and mostly irrelevant, like a full show tech-support capture

When assembling a ServiceNow incident and Arista eAPI interface data into one triage state object, what does the chapter recommend regarding the raw eAPI response?

Include the full eAPI response, including the jsonrpc envelope, so nothing is lost
Strip the transport envelope and JSON-RPC wrapper, then select only the fields the triage decision needs
Convert the eAPI JSON to a single concatenated string before adding it to state
Store it as a separate top-level array state rather than nesting it under the incident

Building State from Network Sources

Key Points

Arista eAPI and Cisco NX-API JSON Output

Arista's eAPI exposes EOS commands over JSON-RPC 2.0: POST to /command-api, authenticate with HTTP basic auth, send a list of commands in one transaction.

{
    "jsonrpc": "2.0",
    "method": "runCmds",
    "params": {"version": 1, "cmds": ["show interfaces", "show vlan"], "format": "json"},
    "id": 1
}

The response is an array with one structured JSON element per command — interface names as keys, nested properties for status, duplex, and error counters. NX-API on Nexus platforms does the same job with a different wrapper: method is cli, cli_array, or cli_ascii, the command goes in params.cmd, and auth issues an nxapi_auth session cookie valid ten minutes. Responses arrive inside an ins_api envelope whose outputs entries hold a TABLE_interface with ROW_interface records. Arista hands you the data directly; Cisco wraps it. Neither wrapper belongs in your state — both are transport artifacts. Strip to the payload, then strip again to the fields the decision needs.

Junos and Aruba CLI Output: Raw Text or Parse First?

Juniper devices are commonly automated through NETCONF (with YANG models), typically via PyEZ — valuable in multi-vendor shops because it is one model to code against instead of a parser per vendor. But NETCONF/PyEZ return XML-derived structures, and Aruba AOS-CX consoles or show tech captures often give nothing but text.

SituationKeep raw textParse first
Short, self-describing outputYes — labels act as field namesUnnecessary overhead
A question needs one value by pathNoYes — cannot path into a blob
Long, mostly irrelevant (show tech-support)No — context rot caseYes, aggressively
Vendor's exact wording carries meaningYesParsing risks losing signal

That last row matters: admin down, notconnect, and errdisabled mean three different things. Collapsing all three to "down" destroys signal before the model sees it. Keep the vendor's own string as the field's value; let the field name supply the structure.

Combining a ServiceNow Incident with Device Telemetry

The running example: an incident lands in ServiceNow, a collector pulls live Arista interface state, and both assemble into one object state. Selection is the step that matters most — out of dozens of eAPI keys per interface, six inform a triage decision:

def summarize_interfaces(eapi_result, names):
    summary = {}
    for name in names:
        raw = eapi_result.get("interfaces", {}).get(name)
        counters = raw.get("interfaceCounters", {})
        summary[name] = {
            "description": raw.get("description"),
            "lineProtocolStatus": raw.get("lineProtocolStatus"),
            "linkStatusChanges": counters.get("linkStatusChanges"),
            "crcErrors": counters.get("inputErrorsDetail", {}).get("crcErrors"),
        }
    return summary

The incident contributes number, short_description, and assignment_group; the assembled object adds device identity, the filtered interfaces, and a recent syslog slice. The same pattern extends to Splunk rows (keep timestamp, host, message; discard search metadata) and NETCONF/PyEZ leaves (pull the two or three the question needs). The collector's job is to hand a small dictionary to the assembly function, which names each part and puts them side by side.

Figure 4.2: Data Source to State Pipeline

flowchart LR A["Arista eAPI"] --> N["Normalize and Filter"] B["Cisco NX-API"] --> N C["Junos NETCONF"] --> N D["Aruba AOS-CX CLI"] --> N E["Splunk Saved Search"] --> N F["ServiceNow Incident"] --> N N --> S["Object State"]

Visual animation — coming soon

Key Takeaway: Arista eAPI and Cisco NX-API both return show output as structured JSON over JSON-RPC 2.0, differing mainly in response wrapping — Arista's direct JSON versus Cisco's ins_api envelope with TABLE/ROW entries. Strip the transport wrapper, select only the fields a decision needs, keep vendor CLI wording raw when its exact phrasing carries meaning, and assemble everything into one named object.
Post-Quiz: Building State from Network Sources

Both Arista eAPI and Cisco NX-API return show command output as structured JSON over JSON-RPC 2.0. What is the main practical difference an engineer must handle when building state from each?

eAPI requires OAuth while NX-API only supports basic auth
Cisco wraps its response in an ins_api envelope with TABLE/ROW entries, while Arista returns the data more directly
NX-API cannot run multiple commands in a single transaction, while eAPI can
eAPI returns XML while NX-API returns JSON

An engineer is deciding whether to keep a show interface block from an Aruba AOS-CX switch as raw text or parse it into named fields. Per the chapter's guidance, when should it stay raw text?

Always — raw text preserves the vendor's exact wording and is simpler to build
When a question needs to reference one specific value from it by path
When the output is short, self-describing, and no question needs to address a specific value by path
When the output is long and mostly irrelevant, like a full show tech-support capture

When assembling a ServiceNow incident and Arista eAPI interface data into one triage state object, what does the chapter recommend regarding the raw eAPI response?

Include the full eAPI response, including the jsonrpc envelope, so nothing is lost
Strip the transport envelope and JSON-RPC wrapper, then select only the fields the triage decision needs
Convert the eAPI JSON to a single concatenated string before adding it to state
Store it as a separate top-level array state rather than nesting it under the incident
Pre-Quiz: Referencing State in Questions

What is the purpose of a dot-and-bracket path like interfaces["Ethernet1"].lineProtocolStatus inside a question's instructions?

It filters the state so only that field is sent to the model
It tells the model which part of the full state a particular judgment should focus on, without removing the rest
It extracts the value in Python before the request is sent
It renames the field for that question only

Why does the chapter recommend putting an escalation policy directly into the state object rather than assuming the model already knows your organization's rules?

Because Noul primitives cannot read text longer than one sentence
Because the model's training data does not reflect your organization's current rules, and TypeSafe advises against relying on knowledge in model weights when current data is available
Because policies must always be arrays of text values, not objects
Because criteria strings in a Choice primitive cannot contain policy language

In a single System One request with three questions — owning_team, impact, and physical_layer_suspected — the impact question cannot be instructed to "use the team you picked in owning_team." Why not?

Because Score primitives cannot reference Choice primitives by type
Because questions do not see each other's answers — each is evaluated against the state independently within the same request
Because the two questions are drawing from separate state objects
Because the token budget only allows one question to reference state per request

Referencing State in Questions

Key Points

Dot-and-Bracket Notation

Once state is a JSON object, question instructions can point at specific fields using dot notation for named fields and bracket indexing for array positions and keys. A path such as ticket.messages[0].text or interfaces["Ethernet1"].lineProtocolStatus clarifies exactly which components should inform a judgment. If you have written a JSONPath in an Ansible filter or an xpath in a NETCONF filter, the syntax looks familiar — the difference is that you are not extracting a value in code, you are telling the model which part of the state a judgment hinges on. The whole state is still present; the path is emphasis, not a filter.

questions={
    "owning_team": Choice(
        instructions="Using incident.short_description and the port states in interfaces, decide the owning team",
        criteria={"data_center": "...", "wan": "...", "wireless": "...", "unknown": "..."},
    ),
    "physical_layer_suspected": Noul(
        instructions='interfaces["Ethernet1"].lineProtocolStatus is down with rising crcErrors, '
                     "pointing at a cable or optic fault rather than a config change",
    ),
}

Note the Noul instruction is written as a statement, not a question, because a Noul returns the probability that the statement is true. One caveat: the model reads instructions literally and is not a calculator — compute thresholds in Python, put the result in state as a named field, and let the question judge what that result means.

Policy Alongside the Request It Governs

The same "keep related information together" guidance that pairs a refund request with its policy maps directly onto network operations. A change-freeze calendar, an escalation matrix, or an SLA tier is the network equivalent of the refund policy. If you want the model to judge whether an incident warrants paging on-call, the escalation policy must be in the state, not assumed. Your escalation matrix changed last quarter; the model's training data did not.

state = {
    "incident": {...},
    "interfaces": interfaces,
    "escalation_policy": (
        "Page on-call immediately for: any spine/core device with an active "
        "traffic-affecting fault; any site isolation. Queue for business hours: "
        "single access-port faults, APs affecting fewer than 20 clients."
    ),
    "change_freeze": {"active": True, "window": "2026-09-15 through 2026-09-19"},
}

Now a Noul instructed "the escalation_policy requires paging the on-call engineer for this incident" is answerable from evidence actually in the request. Without the policy field, the model must guess at your organization's rules — and a confident wrong guess is worse than no answer.

Every Question Sees the Same State Independently

Figure 4.3: Every Question Sees the Same State Independently

flowchart TD S["State Sent Once"] --> Q1["Question: owning_team"] S --> Q2["Question: impact"] S --> Q3["Question: physical_layer_suspected"] Q1 -.-> N1["No visibility into other answers"] Q2 -.-> N1 Q3 -.-> N1

Three consequences follow. First, questions do not see each other's answers — if a decision depends on a prior decision, that is two requests: run the first, write its answer into state as a new field, then run the second. Second, paths scope attention, not visibility — writing a path to one field does not hide the rest of state from that question; every field is visible to every question, which is why filtering discipline is not optional. Third, state and questions share one budget — around 32,000 tokens total — so asking twelve questions instead of three is nearly free on the state side, since you pay for the large interface dump once, not per question.

Key Takeaway: Dot-and-bracket paths such as incident.short_description and interfaces["Ethernet1"].lineProtocolStatus let a question's instructions name exactly which part of state governs it. Put the policies that govern a decision in state alongside the request rather than trusting model weights, and remember that every question sees the whole state independently and shares one token budget with it.
Post-Quiz: Referencing State in Questions

What is the purpose of a dot-and-bracket path like interfaces["Ethernet1"].lineProtocolStatus inside a question's instructions?

It filters the state so only that field is sent to the model
It tells the model which part of the full state a particular judgment should focus on, without removing the rest
It extracts the value in Python before the request is sent
It renames the field for that question only

Why does the chapter recommend putting an escalation policy directly into the state object rather than assuming the model already knows your organization's rules?

Because Noul primitives cannot read text longer than one sentence
Because the model's training data does not reflect your organization's current rules, and TypeSafe advises against relying on knowledge in model weights when current data is available
Because policies must always be arrays of text values, not objects
Because criteria strings in a Choice primitive cannot contain policy language

In a single System One request with three questions — owning_team, impact, and physical_layer_suspected — the impact question cannot be instructed to "use the team you picked in owning_team." Why not?

Because Score primitives cannot reference Choice primitives by type
Because questions do not see each other's answers — each is evaluated against the state independently within the same request
Because the two questions are drawing from separate state objects
Because the token budget only allows one question to reference state per request
Pre-Quiz: Filtering and Token Budget

Per the context rot research cited in the chapter, why are the interface counters for 47 healthy fabric ports more damaging to include alongside one flapping port's counters than an equal amount of unrelated text would be?

Topically related distractors are the same kind of data in the same format, making them maximally confusable with the actual signal
JSON arrays always consume more tokens than prose of the same length
The model processes array state less accurately than object state
Healthy port data triggers a separate, slower reasoning path in the model

In the field-selection audit for the triage decision, why is lastStatusChangeTimestamp dropped from state rather than kept as-is?

It never has diagnostic value for a link-down decision
It's a raw epoch float; the chapter recommends precomputing the elapsed time in Python and adding a derived field like down_for_minutes instead
Timestamps are not one of the three supported state shapes
It duplicates information already present in linkStatusChanges

A team wants to ask twelve separate questions about one incident in a single System One request instead of splitting them into several requests. What does the chapter say about the cost of doing this?

Each additional question roughly multiplies the cost of the state portion of the budget
Adding more questions is nearly free on the state side, since the state is paid for once per request regardless of how many questions reference it
The state and questions draw from separate, independent token budgets
System One silently truncates state once more than five questions are present

Filtering and Token Budget

Key Points

Context Rot: Irrelevant Fields Degrade Answers

Context rot is the phenomenon where model performance degrades progressively as input context grows, even on straightforward retrieval and reasoning tasks. A comprehensive evaluation of 18 leading frontier models found every single one degraded with longer contexts, with severity depending on where relevant information sits and whether topically related distractors are present. The "Lost in the Middle" finding: identical facts placed at different positions scored roughly 70-75% at the beginning, 55-60% in the middle, and 70-75% at the end — a 15-20 point swing from position alone, reproducing across six major model families.

For a network engineer, the mental model is a TCAM: attention is a finite budget diluted across non-essential content. Every token spent on mtu or duplex for a decision hinging on error counters is a token not spent on the error counters. The subtler and more dangerous finding: topically related distractors are worse than obviously irrelevant ones. Counters for 47 healthy ports next to the one flapping port are maximally confusable with the signal, because they are the same kind of data in the same format. TypeSafe's own guidance: "Include only the context relevant to the current questions. This helps the model avoid distractions and context rot."

Selecting Only the Fields a Decision Needs

Decomposing state means asking, field by field, whether the data actually informs the judgment. Applied to the triage decision:

FieldKept?Why
descriptionKeepIdentifies peer and fabric role — informs team ownership
lineProtocolStatusKeepThe core fault signal
linkStatusChanges, crcErrorsKeepFlapping vs. clean transition; physical-layer evidence
bandwidth, mtu, duplexDropIdentical fabric-wide; no discriminating information
lastStatusChangeTimestampDropRaw epoch float — precompute elapsed time instead
Counters for 47 healthy portsDropThe most damaging category — topically related distractors
ins_api / jsonrpc keysDropTransport metadata, no semantic content

Two rows generalize into rules: "precompute, don't ask" (derived values belong in Python; the result goes into state) and "same-shape noise is worst" (be most aggressive filtering data that looks like the signal). Positioning is the last lever — since accuracy is higher at the start and end of a context window, order decision-critical fields first and push long supporting material like escalation_policy lower.

The Roughly 32,000-Token Budget

State and questions draw from the same ~32,000-token pool (~150,000 characters of English text) — but JSON keys, braces, and quotes tokenize less efficiently than prose, so budget conservatively.

def rough_tokens(state_obj) -> int:
    text = state_obj if isinstance(state_obj, str) else json.dumps(state_obj)
    return len(text) // 4

BUDGET = 32_000
estimate = rough_tokens(state)
if estimate > BUDGET * 0.6:
    raise ValueError(f"State is {estimate} tokens; filter before sending.")

response = client.system_one(state=state, questions=questions)
print(response.usage.input_tokens)  # actual count, from the response

The 60% threshold is a working discipline, not a documented limit — it leaves room for questions and criteria strings. The filtered triage state in the running example lands in the low hundreds of tokens; the unfiltered 48-port dump would run to several thousand. The filtered version is cheaper, faster, and more accurate.

Figure 4.4: Before and After Filtering

flowchart TD A["Raw show interfaces output: 48 ports, full field set"] --> B["Select Fields a Decision Needs"] B --> C["Compact Object State: two interfaces, six fields each"] C --> D["Within Token Budget: roughly 32000 tokens"]

Visual animation — coming soon

Key Takeaway: Context rot is measurable degradation from long or noisy context, affecting every frontier model tested, with a documented 15-20 point accuracy swing based on where a fact sits in the window. Include only the fields your questions actually use, be most ruthless about same-shape distractors like healthy-peer counters, put decision-critical fields near the start, and keep the combined state and questions well under the roughly 32,000-token shared budget.
Post-Quiz: Filtering and Token Budget

Per the context rot research cited in the chapter, why are the interface counters for 47 healthy fabric ports more damaging to include alongside one flapping port's counters than an equal amount of unrelated text would be?

Topically related distractors are the same kind of data in the same format, making them maximally confusable with the actual signal
JSON arrays always consume more tokens than prose of the same length
The model processes array state less accurately than object state
Healthy port data triggers a separate, slower reasoning path in the model

In the field-selection audit for the triage decision, why is lastStatusChangeTimestamp dropped from state rather than kept as-is?

It never has diagnostic value for a link-down decision
It's a raw epoch float; the chapter recommends precomputing the elapsed time in Python and adding a derived field like down_for_minutes instead
Timestamps are not one of the three supported state shapes
It duplicates information already present in linkStatusChanges

A team wants to ask twelve separate questions about one incident in a single System One request instead of splitting them into several requests. What does the chapter say about the cost of doing this?

Each additional question roughly multiplies the cost of the state portion of the budget
Adding more questions is nearly free on the state side, since the state is paid for once per request regardless of how many questions reference it
The state and questions draw from separate, independent token budgets
System One silently truncates state once more than five questions are present

Key Terms

TermDefinition
stateThe material a System One request evaluates, supplied as a string, JSON object, or array of text values; it holds content while questions hold the judgments made about that content.
object stateState supplied as a JSON object so each part has a descriptive field name and its relationships stay clear; the recommended default for most requests.
array stateState supplied as an array of text values, used for an ordered sequence of messages or records where position carries meaning.
dot-and-bracket pathA reference in a question's instructions that names a specific part of JSON state using dot notation for fields and brackets for indices or keys, such as ticket.messages[0].text.
context rotProgressive degradation of model accuracy as input context grows or fills with irrelevant content; observed in all 18 frontier models tested.
Lost in the MiddleThe positional-bias form of context rot, where identical facts score roughly 70-75% accuracy at the start or end of a context window but only 55-60% in the middle.
token budgetThe shared limit on a single request's state plus questions, around 32,000 tokens or roughly 150,000 characters of English text.
eAPIArista's Extensible API: a JSON-RPC 2.0 interface on EOS devices, reached by POSTing a runCmds payload to /command-api with HTTP basic auth, returning show output as structured JSON.
NX-APICisco's JSON-RPC 2.0 interface on Nexus switches, using cli, cli_array, or cli_ascii methods with an nxapi_auth session cookie, wrapping responses in an ins_api envelope containing TABLE/ROW structures.
NETCONFThe Network Configuration Protocol, used with YANG data models for standardized cross-platform device communication, commonly on Juniper devices via the PyEZ library.
topically related distractorIrrelevant content that resembles the relevant content in kind and format — such as counters for healthy ports beside a faulted one — and which degrades accuracy more than obviously unrelated content does.
decomposing input stateThe System One design step of including only the context relevant to the current questions, rather than relying on knowledge in model weights when current data is available from your own systems.

Your Progress

Answer Explanations