v1.10.0
·
350 commits
to master
since this release
New & Changed
- feat(web): carry the blast-radius banner strings into Spanish (#1182)
- feat(web): strings for the blast-radius list, its wait and its failure (#1182)
- feat(web): the blast-radius banner lists the affected nodes again (#1182)
- feat(web): plan the blast-radius summary from the one impact response (#1182)
- feat(web): copy for the number slot and the failed preview, en + es (#1180)
- feat(web): a short 'Blast radius' label for the hover card's hop-depth row (#1182)
- feat(web): preview and hint copy, en + es (#1180)
- feat(web): useAssetTagNextPreview (#1180)
- feat(web): cache key for the next-tag preview (#1180)
- feat(web): next-tag preview endpoint client (#1180)
- feat(api): GET /config/asset-tag-scheme/next-tag (#1180)
- feat(shared): contract for the next-tag preview (#1180)
- feat(web): tab the node modal — General, Reported facts, Software, Connections, Changes (#1182)
- feat(web): message keys for the add affordance, the canvas actions and the new tabs (#1181, #1182)
- feat(web): split canvas selection from node detail so the map stays readable (#1182)
- feat(web): the empty map carries the add affordance instead of pointing at it (#1181)
- feat(web): one add control on Topology, agent first and manual behind it (#1181)
- feat(web): blast radius moves onto the map, where its answer is already drawn (#1182)
- feat(web): the node drill-in becomes a large tabbed modal, adapting per node kind (#1182)
- feat(web): let the host-facts projection render without its software list (#1182)
- feat(web): the topology add affordance leads with the reporting agent (#1181)
- feat(web): plan the node-detail tab set from the specs projections, not from source (#1182)
- feat(web): decide re-seed vs conflict when the policy revision moves under a dirty form (#1174)
- updt(web): the es wizard copy states the real Windows constraints (#1168)
- updt(web): the en wizard copy states the real Windows constraints (#1168)
- updt(web): the wizard renders one step structure, and states Windows elevation (#1168)
- updt(web): the policy revision reads once, beside the page title (#1174)
- updt(web): tighten the agent policy copy against the code that backs it (es) (#1174)
- updt(web): tighten the agent policy copy against the code that backs it (en) (#1174)
- feat(web): add the Reporting agents card to the Settings hub (#1174)
- updt(web): Settings -> Instance signposts the moved Reporting agents section (#1174)
- feat(web): Settings -> Reporting agents gets its own route (#1174)
- feat(web): surface the three agent policy scopes and the auto-confirm rules (#1174)
- feat(web): group the agent policy editor into cadence, collection and exclusions (#1174)
- feat(web): Settings i18n (es) for the Reporting agents section (#1174)
- feat(web): Settings i18n (en) for the Reporting agents section (#1174)
- updt(web): per-platform wizard copy in the es catalog (#1168)
- updt(web): per-platform wizard copy in the en catalog (#1168)
- feat(web): a Linux/Windows choice in the "Add a server" wizard (#1168)
- feat(web): hold the wizard's commands to the installers they drive (#1168)
- feat(web): the wizard's install commands, per platform and pure (#1168)
- feat(web): allow /install.ps1 through the auth proxy, by exact path (#1144)
- feat(web): install.ps1 — Scheduled Task as SYSTEM, ACL'd config, MZ + sha256 checks (#1144)
- feat(agent): pin what install.ps1 checks, registers and protects (#1144)
- feat(devops): cross-compile the Windows agent artifacts into the API image (#1144)
- feat(api): serve lazyit-agent--, keeping arch-only requests on Linux (#1144)
- feat(api): pin the os parameter and the legacy arch-only download path (#1144)
- feat(agent): compile the Windows targets, and name every artifact by os and arch (#1144)
- updt(agent): key the report on the platform's own dedup key, not /etc/machine-id (#1144)
- updt(agent): the policy and state cache follow the platform state dir (#1144)
- updt(agent): read the platform config path, with a --config override (#1144)
- feat(agent): resolve the config file and state dir per platform (#1144)
- feat(agent): pin the platform-resolved config and state paths (#1144)
- feat(agent): dispatch the collector by platform, and re-export the shared surface (#1144)
- feat(agent): the Windows collector — one PowerShell call, registry software, docker CLI (#1144)
- feat(agent): pin the Windows collector's mappers, and the two prohibitions (#1144)
- updt(agent): collect.ts becomes collect/linux.ts, importing the shared half (#1144)
- feat(agent): name the OS-neutral half of the collector before adding a second OS (#1144)
- feat(web): es copy for the Changes tab (#1143)
- feat(web): en copy for the Changes tab (#1143)
- feat(web): split the node panel into Overview and Changes tabs (#1143)
- feat(web): the Changes tab body — what moved on this node, newest first (#1143)
- feat(web): useInfraNodeChanges — keyset-paged node fact history (#1143)
- feat(web): read a node's change history from the API (#1143)
- feat(api): GET /infra/nodes/:id/changes (#1143)
- feat(api): record what MOVED on ingest, reusing the #1153 comparison (#1143)
- feat(api): additive migration for infra_node_fact_changes (#1143)
- feat(api): InfraNodeFactChange — an append-only node fact history (#1143)
- feat(shared): export the infra fact-change contract (#1143)
- feat(shared): pure fact diff for the infra node change history (#1143)
- feat(shared): the ack carries the software-delta capability the agent gates its omission on (#1142)
- feat(api): skip the specs write when nothing changed, and sync a container's Asset (#1142, #1153, #1157)
- feat(agent): wire the delta into the report, and answer a resend request (#1142)
- feat(agent): remember the software fingerprint beside the cadence clock (#1142)
- feat(agent): collectSoftware answers with an outcome, not a maybe-list (#1142)
- feat(agent): omit an unchanged package list, always send its fingerprint (#1142)
- feat(shared): softwareState/softwareHash — an absent list can mean keep, never guess (#1142)
- feat(api): serve the x64-baseline artifact and publish its sha256 (#1137)
- feat(web): harden the agent unit, de-phase the timer, verify the binary, and support uninstall (#1137)
- feat(agent): build the pre-AVX2 x64-baseline target and generate checksums (#1137)
- feat(agent): write a .sha256 beside every compiled artifact (#1137)
- feat(agent): 'show' and 'test' — stop diagnosing a silent host by guesswork (#1137)
- feat(agent): --token-file (and stdin), plus the network keys, in config resolution (#1137)
- feat(agent): read an egress proxy and a private CA from the agent's own config (#1137)
- feat(web): the rule form refuses a blanket condition, ANY defaults children off (#1145)
- feat(web): drop hidden rows from the selection and refuse an over-cap batch (#1145)
- feat(web): the tray's two selection rules, where a test can hold them (#1145)
- updt(web): state the stale-threshold ceiling in the es error copy (#1140)
- updt(web): state the stale-threshold ceiling in the en error copy (#1140)
- feat(web): policy badge copy (en+es) (#1140)
- feat(web): show the policy acknowledgement on the node drill-in (#1140)
- feat(web): a policy applied/pending badge on agent-reported nodes (#1140)
- feat(web): agent policy copy (en+es) (#1140)
- feat(web): render the agent policy editor on the instance settings page (#1140)
- feat(web): the fleet agent policy editor in Settings → Instance (#1140)
- feat(web): agent-policy query + save hooks (#1140)
- feat(web): agent-policy read/write endpoints (#1140)
- feat(shared): expose the echoed policy revision on the node drill-in (#1140)
- feat(web): install a fixed 5-minute tick; cadence moves to lazyit (#1140)
- feat(agent): no-op on a tick inside the interval, echo the revision, cache the ack policy (#1140)
- feat(agent): honour the policy — skip disabled collectors, filter by glob, cap software (#1140)
- feat(agent): read the host's own veto limits and add --force (#1140)
- feat(agent): policy + state cache — the local half of the interval inversion (#1140)
- feat(web): group the review tray by host, add select/filter/sort (#1145)
- feat(web): auto-confirm rules manager (#1145)
- feat(web): bulk confirm/discard dialogs with per-scope asset defaults (#1145)
- feat(web): bulk review + auto-confirm rule hooks (#1145)
- feat(web): bulk review + auto-confirm rule endpoints (#1145)
- feat(shared): expose the matchable rule subset + the bulk item type (#1145)
- feat(api): human-only agent-policy routes for the instance, service-account and node scopes (#1140)
- feat(api): judge each node against the staleness threshold it was served, not one global env var (#1140)
- feat(api): the report ack carries the resolved policy and records the echoed revision (#1140)
- feat(api): resolve and write the three agent-policy scopes, read-tolerant and write-strict (#1140)
- feat(api): additive migration for the agent-policy scopes and revision counter (#1140)
- feat(api): agent-policy scopes on InfraNode/ServiceAccount + the singleton settings row (#1140)
- feat(shared): the agent-policy admin wire shape (stored layer + resolved effective) (#1140)
- feat(api): bulk review + auto-confirm rule routes (#1145)
- feat(api): bulk confirm/discard + non-retroactive auto-confirm on create (#1145)
- feat(api): auto-confirm rule storage, CRUD and the read-only matcher (#1145)
- feat(api): auto-scope auto-confirm rule reads to live rows (#1145)
- feat(api): InfraAutoConfirmRule model + additive migration (#1145)
- feat(shared): the report ack carries the resolved agent policy (#1140)
- feat(shared): server-driven agent policy — a closed contract, three-level resolution, local veto, tick gate (#1140)
- feat(shared): bulk review actions + operator-authored auto-confirm rules (#1145)
- feat(shared): the host key a container child was scoped to (#1145)
- feat(web): container panel strings, en + es (#1139)
- feat(web): the node drill-in shows a container child's reported facts (#1139)
- feat(web): a Container panel for the facts the agent reports about a child node (#1139)
- updt(web): the merge dialog says a replaced reporting key is replaced (es) (#1141)
- updt(web): the merge dialog says a replaced reporting key is replaced (en) (#1141)
- feat(shared): export isContainerChildExternalId — the key's own rule, not a call-site string (#1139)
- feat(web): merge-into copy (en + es) (#1141)
- feat(web): render the infra.identity_conflict nudge in the bell (#1141)
- feat(web): a third tray action — merge a proposal into the server it already is (#1141)
- feat(web): the merge-into dialog with re-image adoption suggestions (#1141)
- feat(web): useMergeInfraNode + useInfraIdentityMatches hooks (#1141)
- feat(web): identity-matches + merge-into data access (#1141)
- feat(api): propose the node kind on create and reconcile container children (#1139)
- feat(api): expose the merge-into and identity-matches endpoints (#1141)
- feat(api): corroborate identity on match, split colliding hosts, add node re-key/merge (#1141)
- feat(api): tryCharge — one shared budget, a non-throwing refusal for child nodes (#1139)
- feat(agent): read the local container runtime and ship host.containers[] (#1139)
- feat(shared): a container port emits only the keys the runtime reported (#1139)
- feat(shared): add the infra.identity_conflict notification type (#1141)
- feat(shared): corroborating host identity evidence, clone detection, disambiguated dedup key (#1141)
- feat(shared): host.containers[] on the wire, plus the kind + container-identity mappers (#1139)
- feat(agent): distinguish "probe absent" from "bare metal", carry IPv6 context (#1138)
- feat(api): persist report diagnostics, record skew at any depth, close the confirm leak (#1138)
- feat(shared): contract v2 corrections — canonical identity, stable IPv6, whole-body skew (#1138)
- feat(agent): send diagnostics with every report and echo warnings locally (#1138)
- feat(agent): collect the contract v2 Linux facts + report degraded collectors (#1138)
- feat(agent): pin the bounded, always-present diagnostics block (#1138)
- feat(agent): pin the contract v2 collectors — os.family, chassis, virt, nics, warnings (#1138)
- feat(api): forward the raw report body so dropped root keys stay diagnosable (#1138)
- feat(api): pin the raw report body reaching ingestReport (#1138)
- feat(api): record the report root keys an older server dropped; promote IPv6 (#1138)
- feat(api): pin contract v2 tolerance + unknown-root-key recording on report ingest (#1138)
- feat(shared): agent report contract v2 — os.family, chassis, virtualization, identifiers, ipv6, diagnostics (#1138)
- feat(shared): pin agent report contract v2 — pre-v2 reports must round-trip (#1138)
- feat(api): resolveJsonBodyLimit — explicit JSON body limit resolver (#1132)
Fixes
- fix(web): keep the affected list mounted while collapsed (#1182)
- fix(web): the in-flight sentence was muted while its own comment claimed otherwise (#1182)
- fix(web): carry the corrected Software empty state into Spanish (#1142)
- fix(web): the Software empty state asserted a collector rule Windows can break (#1142)
- fix(web): apply ?node= whenever the URL changes it, not only on mount (#1182)
- fix(web): a Table row click landed on the Map selecting nothing (#1182)
- fix(web): key the shape parts by position, since a prefix and a suffix can match (#1180)
- fix(web): the settings card stops showing an already-taken tag when the scheme is off (#1180)
- fix(api): the relation guard skipped fields it could not classify (#1179)
- fix(web): the scheme-off preview is a shape, and a failed lookup is its own state (#1180)
- fix(web): carry the corrected Software empty state into Spanish (#1182)
- fix(web): the Software tab's empty state said the agent didn't report, when it had (#1182)
- fix(web): the add menu hard-coded its item order, so the test that pins it proved nothing (#1181)
- fix(web): read the banner's tone from the shared table so its text stays neutral (#1182)
- fix(web): the on-canvas blast-radius banner painted its text in a hue that fails AA (#1182)
- fix(web): the hop-depth row needed its own short label, not the section title (#1182)
- fix(web): stop the create form's static example from impersonating a real tag (#1180)
- fix(web): the settings preview now shows the tag that would actually be allocated (#1180)
- fix(api): make the tag preview run the allocator's own skip-existing lookup (#1180)
- fix(api): InfraAutoConfirmRule.createdById was missing @db.Uuid (#1179)
- fix(agent): "the agent never reads PATH" was false on Windows (#1167)
- fix(agent): the Windows install directory was never put on PATH (#1167)
- fix(web): the veto direction is a floor, not a guarantee of "less" (es) (#1174)
- fix(web): the veto direction is a floor, not a guarantee of "less" (#1174)
- fix(web): surface a policy written elsewhere instead of overwriting the edit (#1174)
- fix(web): mirror the two-OS collector claim and the veto in the footer, and agree the rule-count plural (es) (#1174)
- fix(web): the "off is never run" claim was Linux-only, and the scopes footer omitted the local veto (#1174)
- fix(agent): drop the unmerged-PR reference and name the constructs that are case-insensitive (#1166)
- fix(agent): the scheme check in install.ps1 is -notmatch, not -match (#1166)
- fix(agent): name the one JS/.NET regex difference that could matter, and why it cannot (#1166)
- fix(agent): a root runner falls into the install path, not 'a real install' (#1166)
- fix(agent): the BOM comment called install.sh fatal; measured, it prints an error and installs anyway
- fix(web): the Windows inspect-first step downloaded install.ps1 into System32 (#1168)
- fix(agent): the -Url guard missed a prefixed install.ps1 and suggested a broken URL (#1166)
- fix(agent): the origin-suggestion assertion must read code, not the comment quoting the old form (#1166)
- fix(agent): evaluate the -Url guard's patterns instead of grepping their text (#1166)
- fix(agent): the --url guard missed a prefixed install.sh and suggested a broken URL (#1166)
- fix(agent): run the --url guard instead of grepping it, and pin the shapes it misses (#1166)
- fix(agent): the BOM check covered one installer and claimed the ASCII rule backed it up (#1166)
- fix(web): the empty exclusion counter read "Sin patrones de 32" (es) (#1174)
- fix(web): the empty exclusion counter read "No patterns of 32" (en) (#1174)
- fix(agent): --url pointing at install.sh failed looking like a token problem (#1166)
- fix(agent): anchor the install.sh download assertion on the curl, not the help text (#1166)
- fix(agent): a -Url pointing at install.ps1 failed looking like a token problem (#1166)
- fix(agent): pin the same base-url guard for install.sh (#1166)
- fix(agent): pin that install.ps1 names a wrong -Url instead of blaming the token (#1166)
- fix(agent): install.sh is the source the em dashes were copied from, so it goes ASCII too (#1166)
- fix(agent): install.ps1 was UTF-8 without a BOM, so PowerShell 5.1 could not parse it (#1166)
- fix(agent): the installers had no guard against the encoding that broke one (#1166)
- fix(agent): a per-fact failure in the Windows sweep degraded with no warning (#1144)
- fix(api): answer the policy-generation question server-side, from what it already holds (#1143)
- fix(shared): an exclusion glob is not an uninstall — guard the whole policy-sensitive class (#1143)
- fix(web): the repetition fallback did not cover the call that validates the duration (#1144)
- fix(api): the identity-collision remedy told a Windows operator to run a Linux command (#1144)
- fix(agent): pin the random delay to the time trigger (#1144)
- fix(web): a boot trigger has no RandomDelay element to put one in (#1144)
- fix(api): the pre-rename fallback had no test defending it (#1144)
- fix(agent): cover the two impure boundaries, not just the pure mappers (#1144)
- fix(agent): the docker lookup was the same unverified boundary as the pipe (#1144)
- fix(agent): pin two triggers, and the parameter that does not exist (#1144)
- fix(web): the Scheduled Task never ticked until the host rebooted (#1144)
- fix(api): carry the cap's index in the same unshipped migration (#1143)
- fix(api): index the abuse cap so it stops being the expensive query (#1143)
- fix(api): a page of history must not read the node's whole specs blob (#1143)
- fix(shared): an emptied disk list is no evidence, not two disks vanishing (#1143)
- fix(api): the added package read-back must not be able to fail a report (#1143)
- fix(web): the empty Changes state assumed every node has an agent (#1143)
- fix(web): own the panel's open-tab state (#1143)
- fix(web): take the tab gate as a prop instead of inheriting it (#1143)
- fix(web): gate the changes query on the open tab explicitly (#1143)
- fix(shared): two JSDoc claims the diff did not keep (#1143)
- fix(api): a re-ordered package list is not a changed one on the Asset either (#1153)
- fix(api): a hand-edited scalar
specsdegrades instead of failing a check-in (#1153) - fix(api): the Asset mirrors what the node HOLDS when the write is skipped (#1153)
- fix(api): a claim the server cannot check is the LEAST trusted, not the most (#1142)
- fix(web): a re-install no longer deletes a lowercase proxy line (#1137)
- fix(api): the re-point 400 says the orphan is conditional on lazyit having auto-created the asset (#1117)
- fix(agent): send the test probe twice, and silence the ambient proxy once (#1137)
- fix(agent): a lone 404 is not proof of anything — probe token-less first (#1137)
- fix(api): every ack states this build's software-delta capability, and three comments the write skip falsified (#1142, #1153)
- fix(api): refuse only the RE-POINT — first-attach stays, gated by assertExists (#1117)
- fix(agent): gate the software omission on the ack's capability, refreshed every report (#1142)
- fix(shared): assetId accepts a cuid again — the re-point rule needs the stored row (#1117)
- fix(agent): remember the server's delta capability in state.json, read strictly (#1142)
- fix(agent): omit the package list only after the server proves it understands the delta (#1142)
- fix(api): the server fingerprints the list it stores — the skip must not need the client (#1153)
- fix(web): mirror the corrected inventory stamp in es (#1153)
- fix(agent): a 429 on the probe is not lazyit's report limit — that guard is route-scoped (#1137)
- fix(web): the inventory stamp dates the facts, not the check-in (#1153)
- fix(web): keep the software fingerprint out of the custom-fields grid (#1142)
- fix(api): refuse an infra node asset re-point, detach only (#1117)
- fix(shared): a node patch may DETACH the asset link, never re-point it (#1117)
- fix(api): same correction in the patch 400 — no condition, not confirms-everything (#1145)
- fix(shared): the new patch message repeated the overstatement it was fixing (#1145)
- fix(web): mirror the corrected wildcard copy in the es rule form (#1145)
- fix(web): the rule form told the operator a wildcard-only pattern matches every host (#1145)
- fix(api): the patch 400 names the merged rule, and the JSDoc stops overstating wildcards (#1145)
- fix(shared): judge a rule patch by the merged rule, and stop overstating the wildcard refusal (#1145)
- fix(web): the count, the dialogs and the request all read the visible selection (#1145)
- fix(web): scope the selection to the visible rows instead of pruning in an effect (#1145)
- fix(api): a human discard outranks every auto-confirm rule (#1145)
- fix(web): the stale-threshold editor never checked its 7-day ceiling (#1140)
- fix(web): re-running install.sh must not erase this host's own agent limits (#1140)
- fix(api): reject blanket rules on merge and default ANY-scope children off (#1145)
- fix(shared): refuse a rule whose conditions can exclude nothing (#1145)
- fix(api): only stamp a served staleness on a node whose agent echoed a policy revision (#1140)
- fix(shared): a server glob list at the cap must not displace the host's own exclusions (#1140)
- fix(shared): subtract the per-machine jitter so a tick can never be skipped (#1140)
- fix(web): the wizard's manual first report needs --force now the interval gates it (#1140)
- fix(web): the merge dialog described a narrower action than merge performs (es) (#1141)
- fix(web): the merge dialog described a narrower action than merge performs (en) (#1141)
- fix(shared): the identity_conflict catalog entry stated the very rule this PR removed (#1141)
- fix(web): don't ask next-intl for a state label the panel has no message for (#1139)
- fix(web): render a confirmed container's facts instead of dumping its blob (#1139)
- fix(api): the enrollment budget must never retire a running container (#1139)
- fix(api): durable conflict marker, restorable merge source, and a P2002 fallback on the collision branch (#1141)
- fix(agent): the container collector gated on a check that is false for a socket (#1139)
- fix(shared): drop the hostname gate from the cloned-machine-id rule (#1141)
- fix(web): keep the #1141 node-blob bookkeeping out of the custom-fields dump
- fix(api): make the two "NEVER splits" guards actually bite (#1141)
- fix(api): lead the identity-conflict summary with the remedy — the bell truncates to one line (#1141)
- fix(web): the agent wizard must announce the SERVER, not one of its containers (#1139)
- fix(agent): buildIdentifiers sanitizes instead of only normalizing (#1138)
- fix(shared): sanitize identifier values with the existing serial junk rule, degrade malformed elements (#1138)
- fix(api): check the body-limit fixture against the WIRE type, not the parsed one (#1138)
- fix(web): keep the report diagnostics out of the node panel's custom fields (#1138)
- fix(api): make AgentReportSkew a type alias so it satisfies Prisma's jsonb input (#1138)
- fix: repair ADR-0074 — merge resolution had duplicated §4-§8
- fix(web): type the add-edge target picker on InfraNodeListItem (#1135)
- fix(web): type the canvas board on InfraNodeListItem, not InfraNode (#1135)
- fix(api): lean select projection for GET /infra/nodes, dropping specs (#1135)
- fix(api): assert listNodes projects an explicit column list without specs (#1135)
- fix(shared): omit specs from InfraNodeListItemSchema (#1135)
- fix(shared): pin the node list contract — no specs on a list row (#1135)
- fix(agent): RuntimeMaxSec=120 on the systemd unit — the timer can no longer be starved (#1133)
- fix(agent): bound the report POST with AbortSignal.timeout (#1133)
- fix(agent): tests for the collector's bounded-wait contract (#1133)
- fix(agent): bound every collector with a spawn timeout — a wedged lsblk no longer hangs the run (#1133)
- fix(api): set the JSON body limit at bootstrap — unblocks package-heavy agent reports (#1132)
- fix(api): regression test — a 5000-package agent report must round-trip (#1132)
Removed
- del(web): drop the unused impact section title in Spanish too (#1182)
- del(web): drop the impact section title the blast-radius move left unused (#1182)
- del(web): drop the onboarded 'Add agent' button the header affordance duplicates (#1181)
- del(web): the agent policy editor moved out of Settings -> Instance (#1174)
- del(api): remove the reportedBySaId migration (never merged, never deployed)
- del(api): drop InfraNode.reportedBySaId — the rate throttle needs no column
Full changelog: v1.9.0...v1.10.0