Observation
core.parse_osquery_results accepts exactly one shape — a dict keyed by query name:
{ "fips_not_enforced": [ {...rows...} ], ... }
That's the shape the bundled demo fixtures use, and it's clean for the mapper. But it is not the shape osquery's scheduled-query logger actually emits. A real osqueryd results log is newline-delimited JSON, one event per line:
{"name":"fips_not_enforced","hostIdentifier":"web01","calendarTime":"...","action":"snapshot","snapshot":[{...}]}
{"name":"ssh_root_login_permitted","hostIdentifier":"web01","action":"added","columns":{...}}
(#PR that added shape hardening already flags bare-list single-query output as a diagnostic — this is the complementary gap on the other end.)
Why it matters
An operator who points the tool at the osqueryd results log they already collect gets zero findings, because none of the top-level keys are query names. They have to pre-transform the log into the {query_name: [rows]} shape by hand, which defeats "point it at your osquery output".
Suggested approach
Add a parser branch that detects the NDJSON snapshot/differential log shape (records with name + snapshot/columns + optional hostIdentifier/action), groups by name, and — bonus — uses hostIdentifier for per-host attribution in fleet.scan_host instead of only the filename stem. Keep the existing dict shape working. Purely additive.
Observation
core.parse_osquery_resultsaccepts exactly one shape — a dict keyed by query name:{ "fips_not_enforced": [ {...rows...} ], ... }That's the shape the bundled demo fixtures use, and it's clean for the mapper. But it is not the shape osquery's scheduled-query logger actually emits. A real osqueryd results log is newline-delimited JSON, one event per line:
{"name":"fips_not_enforced","hostIdentifier":"web01","calendarTime":"...","action":"snapshot","snapshot":[{...}]} {"name":"ssh_root_login_permitted","hostIdentifier":"web01","action":"added","columns":{...}}(#PR that added shape hardening already flags bare-list single-query output as a diagnostic — this is the complementary gap on the other end.)
Why it matters
An operator who points the tool at the osqueryd results log they already collect gets zero findings, because none of the top-level keys are query names. They have to pre-transform the log into the
{query_name: [rows]}shape by hand, which defeats "point it at your osquery output".Suggested approach
Add a parser branch that detects the NDJSON snapshot/differential log shape (records with
name+snapshot/columns+ optionalhostIdentifier/action), groups byname, and — bonus — useshostIdentifierfor per-host attribution infleet.scan_hostinstead of only the filename stem. Keep the existing dict shape working. Purely additive.