Commit Graph

3027 Commits

Author SHA1 Message Date
Claude 762fef4e24 Landing page bakes the platform stats of the deploy into its static HTML; browsers then swap in the live numbers
Crawlers and LLM fetchers run no JS and saw only the skeleton of the stats
band. app/page.tsx now awaits one read of the public stats blob during
next build (lib/platformStats.ts: manifest, then the versioned file it
names) and renders the numbers into the export. StatsBand starts from that
snapshot and replaces it with the live numbers; a failed live read keeps
the baked numbers instead of hiding the band.

The read is awaited at page level, not under Suspense: React moves a
resolved boundary of a page this size into a hidden div at the end of the
body. It uses no-store (route force-static), so Next's fetch cache cannot
hand a later build the previous numbers. Fail-soft: without a snapshot the
page ships the skeleton and loads live as before, and deploy-web.yml warns.

The browser now revalidates both files (no-cache instead of force-cache):
the backend rewrites the per-day file every 2 hours under immutable, so a
copy cached earlier that day would have made the numbers drop after load.

The page body moved to components/landing/LandingPage.tsx, which the
marketing guards render synchronously; StatsBand left the .json() ratchet
baseline; the sitemap lastmod of / includes the body.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4ddfosgdeCwXo7NvB9xd2
2026-10-03 03:27:20 +00:00
Oliver Kieselbach bca492ba05 bump pointer: internal (agent v2.0.1474 released, B-6dx field verify, time-attribution deploy steps)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 23:06:40 +02:00
Oliver Kieselbach e7dd962133 bump pointer: internal (time attribution v4 D-314, OOBE update page agent fixes, backlog B-q3z/B-6dx/B-dbf; member list lesson)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
v2.0.1474
2026-10-02 22:57:10 +02:00
Oliver Kieselbach 14a67ef5af Time attribution shows the OOBE quality update as Windows Update and the wait after its restart as Waiting for sign-in (D-314)
TimeAttributionCalculator v4 cuts two segments out of the phase partition:
os_update from the OobeNDUP page start whose visit holds update evidence
(a servicing step or a name only an update in progress writes) to the last
update evidence before the user is back; awaiting_sign_in from there to the
first evidence of the user, only after a restart. Both replace the phase
span they overlap; without evidence the partition is v3's. OsUpdates names
the KBs and restarts. Reboot gaps no longer start or end on the clock-sync
row logged at boot. The sweep recomputes the last 30 days.

Aggregates carry eight segments; the session lane and Fleet Health show
"Windows Update" (cyan) and "Waiting for sign-in" (sky) with the KBs and
restarts in legend and tooltip; MCP get_time_attribution description;
manifest and wire types regenerated.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 22:55:45 +02:00
Oliver Kieselbach 2371855b77 OOBE update page: fields from event properties in every display language, page start and stop never capped, no duplicates after a restart
ShellCoreTracker reads CXID, result, name and value from the event properties
(62404..62407 %1/%2), live and in the backfill. The formatted message is
localized: German devices lost result and value, French devices reported no
update page at all. The text patterns stay as the fallback and accept
guillemets. The Hello-wizard start reads the CXID property too.

OobeUpdateTelemetry: page start and stop sit outside the run budget (at most
3 per page), names share a budget of 150 (was 50; the cloud page logs ~45
init names in its first 40 s). ReportPage returns whether it reported.

A RecordId watermark (shellcore-page-watermark.json) claims every update-page
record and persists reported ones, so the restart backfill does not send the
minutes before the restart again. EspAndHelloTracker passes the state
directory.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 22:55:39 +02:00
Oliver Kieselbach 3a50de83ef Add-member input keeps a minimum width and wraps instead of shrinking (D-313)
The form no longer lays out by viewport breakpoint: a wide window can host a
narrow column next to the settings sidebar, where the input shrank to a few
characters. The input now grows from an 18rem basis and wraps below the type
switch when the row has no room; role and Add wrap together.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 22:51:28 +02:00
Oliver Kieselbach 24dfd247e9 bump pointer: internal (viewer app role + member list live, D-313, lesson)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 21:18:14 +02:00
Oliver Kieselbach a640039518 Member role changes need an explicit Save; the GA add form gives the input its own line (D-312)
- An open member row keeps role and bootstrap permission as a draft:
  Save writes it, Discard or closing the row drops it, so a stray select
  change no longer alters anyone's access.
- AddMemberForm takes `stacked` for narrow hosts; the GA tenant editor
  modal uses it, so the email field spans the full width there.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 21:13:11 +02:00
Oliver Kieselbach c3e9011905 bump pointer: internal (D-312, plan viewer-app-role-and-member-list, B-8gf/B-7w2)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 20:36:37 +02:00
Oliver Kieselbach 8f6926a945 Viewer can come from an Entra app role; Access Management lists one line per member (D-312)
- EntraAppRoleResolver maps the Viewer app role next to Admin and Operator
  (the highest role wins); a claim Viewer gets no bootstrap-token rights.
- The tenant settings page and the GA tenant editor share components/members:
  one line per member, a click opens who added it and the actions, Remove
  asks in the row, role chips with counts, a search, 25 rows per page. A
  vanished chip or a shrunken list moves the selection, so the list never
  shows an empty page and never snaps back.
- The add form sits above the list, About Roles is collapsed, and a tenant
  with Entra app roles enabled sees that those users are not listed.
- The EntraAppRolesEnabled doc names Viewer; manifest and generated wire
  types regenerated.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 20:32:54 +02:00
Oliver Kieselbach 01323fdf6d ProgressAccessHint test matches the docs link as a substring, not a RegExp
CodeQL js/incomplete-hostname-regexp (alert #96) traced DOCS_URL into the
RegExp built in the "Learn more" assertion. The dots were escaped with
[.], which CodeQL does not recognize as a sanitizer. A substring match
on the exact markup needs no escaping and keeps the same checks: a space
after the sentence, the exact href with target/rel, and "Learn more" as
the link text.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 20:17:46 +02:00
Oliver Kieselbach c566ed818b bump pointer: internal (access hint released, B-u5a verify only)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 17:01:38 +02:00
Oliver Kieselbach 3a40361bb6 bump pointer: internal (access-hint follow-up, docs-corpus URL invariant)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 16:54:52 +02:00
Oliver Kieselbach 1b988d2943 Docs links use the URL GitBook publishes: access hint via the docs path registry, MCP citations from SUMMARY.md groups
GitBook publishes a page under the slug of its SUMMARY.md group, not its
folder: troubleshooting/ is /troubleshooting-and-support/, trust/ is
/trust-and-security/. A folder URL works only for pages that predate the
group rename (307); for a newer page it is a 404.

- Web: the Progress Portal access hint linked the new troubleshooting
  article by folder path (404 live). It now uses DOCS_PATHS.progressPortalOnly.
- MCP: docUrl built folder URLs for every search_docs citation. Live census
  over all 58 SUMMARY pages: 47 direct, 10 via redirect, 1 dead.
  summaryFolderSlugs now derives the segments from SUMMARY.md; all 60 page
  URLs of the real corpus answer 200.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 16:54:40 +02:00
Oliver Kieselbach e88a0e455c Progress Portal access hint links to its troubleshooting article
Both variants end with a muted "Learn more" to
troubleshooting/progress-portal-only in the customer docs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 16:35:37 +02:00
Oliver Kieselbach 0695f7943c bump pointers: internal (D-311, plan progress-portal-access-hint, B-zr9/B-u5a), commands (platform-health marker)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 16:20:50 +02:00
Oliver Kieselbach 6f8e7d48b2 Progress Portal tells members without a role whom to ask for access; activation lands every role where sign-in would
A member without a portal role only ever sees the Progress Portal and never
learned that their organization already runs the full product. Below the
search they now see one muted line: ask your Autopilot Monitor admin for a
role. When the organization holds no session and signed up more than 14 days
ago, the line names the signup date and the support mailbox instead.

- GET progress/tenant-status (AuthenticatedUser, JWT tenant only, no session
  data): unused flag plus signup date. Both reads are strict, so a storage
  failure is a 500 and never reads as "unused".
- ISessionRepository.HasAnySessionStrictAsync: key-only probe on
  SessionsIndex with the primary-table fallback, no catch.
- ProgressTenantStatusResponse + wire parity facts; regenerated manifests and
  web/MCP wire types.
- lib/landingTarget.ts: one landing decision for the landing gate and the
  activation page. Leaving activation no longer sends Operators, Viewers,
  Global Readers and delegated admins to the Progress Portal, and it keeps
  the deep link the landing gate saved during activation.
- lib/supportContact.ts: one source for the support address.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 16:20:38 +02:00
Oliver Kieselbach 0248d14738 bump pointer: internal (IME diff notes 1.106.106.0 + 1.105.154.0, B-4v2)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 16:01:05 +02:00
Oliver Kieselbach dc59fea6e5 bump pointer: internal (OOBE update phase: DEV-004 live, agent v2.0.1473 in Shadow)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 15:28:34 +02:00
Oliver Kieselbach 08455cc5f9 OOBE quality update: install events from the System log, servicing steps, a bounded engine phase in Shadow mode (D-310)
Report 3a2207978e4c: a session was failed 30 min after the ESP exit while Windows installed its
OOBE quality update. The update watcher had been blind since July and the engine had no notion
of the phase.

- Windows Update client: 19/20/43/44 come from the System log (provider-filtered XPath), as the
  provider manifest routes them; 25/26/31/41 from Operational via their own config list.
  Updates are classified os/defender/store/other: only Windows/.NET updates become rows, the
  rest is counted into windows_update_activity_summary. Per-channel watermarks persist a record
  only after its row and engine signal were handed to the ingress.
- Servicing: CBS steps from the Setup log (windows_update_servicing), client UpdateAgentLCU.
- Engine: OsUpdateActivity and OsUpdateFacts (event-time ordered) anchor an OOBE update phase
  after the ESP exit. Each state has its own bound: the update runs at most 3 h (then Failed
  oobe_update_not_finished), after it the user has 60 min to sign in (then the engine stops
  waiting without a verdict), after the sign-in one window of grace.
- The phase acts only in OobeUpdatePhaseMode=Active. Shadow, the default, reports what it would
  decide as oobe_update_phase_shadow right before today's verdict. The agent stamps the mode on
  EnrollmentFactsObserved at every start; a later stamp can take Active away, never grant it.
- Agent: a stop without a verdict ends the session like the max-lifetime watchdog
  (agent_shutting_down reason=stopped_waiting); the backend classifies it honestly (verdict
  origin stopwait), never Failed.
- Measurement: oobe_update_page (the update page and its ExpeditedUpdate_* names; a 62407 value
  only as boolean, integer or HRESULT) and oobe_update_state (NDUP and ESP-policy registry
  values), both Debug and bounded per run.
- ANALYZE-DEV-004 1.2.0 counts install and download failures only, never scan failures.
- Event types in Constants, MCP catalog and web; shared manifests regenerated; privacy page
  names Windows updates installed during the enrollment.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
v2.0.1473
2026-10-02 15:09:50 +02:00
Oliver Kieselbach 87c5bf018c bump pointer: internal (gather-rule state released, B-hx3 field verify)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 22:26:18 +02:00
Oliver Kieselbach 0d6c03d64b Public texts no longer name a customer domain or IME decompiles
- Two code comments of the gather-rule timeline feed named a customer's domain next to the
  session id; the session id stays as the regression anchor.
- The get_ime_pattern_health description and the IME Pattern Health admin text no longer send
  the reader to "the IME decompile"; the IME-TOKEN-FAILURE and IME-DO-TEL pattern descriptions
  say "verified against IME x" / "absent from the x builds" (rules/dist regenerated).
- Code comments that cited decompiled IME builds cite the IME version instead.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
v2.0.1472
2026-10-01 22:00:52 +02:00
Oliver Kieselbach b14866c9a6 bump pointer: internal (gather-rule state committed, B-hx3)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 21:46:44 +02:00
Oliver Kieselbach 25b133d3d0 bump pointer: internal (gather-rule state across restarts, D-309)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 21:45:29 +02:00
Oliver Kieselbach 684167292f Gather rules keep their place across agent restarts; byte-exact logparser reader; MCP filters by gather event types
- Logparser positions per (rule, file) and the on_change values persist in
  State\gather-rule-state.json, bound to the session id. A reboot, hard kill or WhiteGlove
  Part 2 no longer replays a log from byte 0 or re-emits an unchanged on_change result. A
  replaced log (fingerprint of its first 4 KB) is read from the beginning. Positions are saved
  after the events went out; restoring the file is fail-soft. --run-gather-rules stays in memory.
- LogLineReader: a maxLines stop loses no line, an unfinished last line is never split
  (interval rules wait one run, one-shot triggers read it again next run), UTF-16/UTF-32 logs
  are read by their byte order mark from any position, line ends as StreamReader.ReadLine,
  logLineNumber counts from the start of the file, lines over 32 MB are skipped. A maxLines
  value that is no positive number falls back to 1000.
- UserProfileResolver no longer caches "no user signed in yet" (detection retried at most
  every 30 s); guarded callers expand the token with the profile they checked.
- MCP get_session_events, search_sessions_by_event and query_raw_events accept a gather
  rule's own outputEventType; an empty first-page result for an uncatalogued type carries
  eventTypeNote with the closest built-in types instead of being rejected up front.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 21:45:10 +02:00
Oliver Kieselbach 6474860a57 bump pointer: internal (lesson from the vulnerabilities feedback)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 20:15:56 +02:00
Oliver Kieselbach d23f2eae3e bump pointer: internal (vulnerabilities feedback fixes, D-308)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 20:14:40 +02:00
Oliver Kieselbach fae6aa0b92 Vulnerabilities band filters always find entries, list controls stay put, first load shows the progress dialog
The summary endpoint takes perBand: above 0 it adds bandCves and bandSoftware, each severity and
priority band's top entries outside the lists. The portal asks for 10 per band and shows them only
under a filter, so Attend lists its 7 CVEs instead of nothing; the MCP tool never asks and keeps its
size. The Most exposed controls sit below the title in every state, bands with 0 entries are
disabled, and the first load shows CalculatingDialog (the Geographic Performance dialog without its
page) with separate estimates for all tenants and one tenant. D-308.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 20:13:47 +02:00
Oliver Kieselbach 43dfb731f1 bump pointer: internal (vulnerabilities tab redesign, D-307)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 19:38:45 +02:00
Oliver Kieselbach dd5534b0c9 Vulnerabilities tab shows a severity donut, the priority ladder and the most exposed software
The exposure summary groups CVE index rows by product: every new row carries the finding's
CPE vendor:product as Product, and a row without it borrows the product of a row with the
same title. The summary adds topSoftware, distinctSoftware and kevAffectedSessions, and
known-exploited CVEs and products stay listed below the topN cut (capped so the MCP result
stays under its 50k cap). The shared panel is rebuilt: KPI tiles, a severity donut and the
Act/Attend/Track ladder as list filters, and a Most exposed card with Software and CVEs
lenses. get_vulnerability_summary describes the new fields. D-307.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 19:35:09 +02:00
Oliver Kieselbach 54334de378 Rule pages point to AI-assisted rule authoring
The community box on the gather and analyze rule pages gets a line that an
assistant connected via MCP can draft, validate and test a rule, linking the
AI-assisted rule authoring docs page.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 19:11:56 +02:00
Oliver Kieselbach 9671191eef bump pointer: internal (/plans nav marking, slash links, MCP docs, D-306)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 18:43:41 +02:00
Oliver Kieselbach c5a4feb762 Internal links on the public pages end with a slash
The host answers /plans, /about, /privacy and the other page paths with a
301 to the slash path first. The navbar, the footer, the landing and
get-started calls to action, the terms page and two portal links to
/settings now point at the slash path directly. A guard renders every
public page with the build's trailing-slash setting and fails on an
internal link without it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 18:41:22 +02:00
Oliver Kieselbach 2253fca533 bump pointers: internal, .claude/commands (AI page and marketing click counts, D-305)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 18:16:42 +02:00
Oliver Kieselbach ff9e79dcc7 Landing gets an AI page (/ai) and counts clicks and section views
New public page /ai, linked from the navbar (AI), the Then just ask section
and the footer. It shows what an AI client can answer from the structured
enrollment data: a question gallery whose answer panel switches between chat
app, VS Code, terminal and self-hosted, the data path (where the model runs,
what reaches us) and how to connect. A test keeps every MCP tool and argument
on the page in line with the server's registrations for tenant users.

The landing, /get-started and /ai send anonymous click and section-view
counts (marketing_cta_clicked, marketing_section_viewed); every link and
button carries a data-track id. Layouts with their own OpenGraph metadata
keep the shared image and the large Twitter card again. The navbar tightens
between lg and xl so the new entry fits at 1024 px. The FAQ names the
documented MCP clients, and the terminal demo uses the real search_sessions
argument (deviceName).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 18:15:15 +02:00
Oliver Kieselbach e54b4585b8 bump pointers: internal, .claude/commands (event follow-up page live, D-304)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 17:17:41 +02:00
Oliver Kieselbach 7894d61e0b Event follow-up page for the Workplace Ninja Summit 2026
Unlisted page /events/<slug>/ for the link in the post-event mail: try it,
request a walkthrough, read the docs, plus the free community editions of
SCEPman and MyWorkID. It is noindex and kept out of the sitemap, robots.txt
and llms.txt. Every call to action sends one anonymous click event
(event_followup_clicked). The customer quote is now shared with the landing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 17:11:48 +02:00
Oliver Kieselbach 090f47d4fb Merge branch 'main' of https://github.com/okieselbach/AutopilotMonitor 2026-10-01 13:14:44 +02:00
Oliver Kieselbach c2d68b6537 bump pointer: internal (landing GitHub stars, D-303)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 13:13:35 +02:00
Oliver Kieselbach 5b0dfaad99 Landing shows the GitHub star count and a customer quote
The navbar gets a "Star" pill with the repository's star count from sm up;
phones keep the bare GitHub mark. A new section before the closing CTA
shows one customer quote with a star ask underneath. The footer's
"Star us on GitHub" line is gone, so the page asks twice, not three times.

The count is read once per web deploy (deploy-web.yml, own step, job token
only there) and inlined by next build as NEXT_PUBLIC_GITHUB_STARS, so
visitors' browsers never contact GitHub and the CSP stays as it is.
Without a value the pill renders without a counter (D-303).

The desktop links, bell and sign-in now start at lg instead of md: the bar
already overflowed between 768 and ~1000 px and the pill widened it further.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 13:13:33 +02:00
dependabot[bot] 50d29e61e8 chore(deps): bump the web-security group across 1 directory with 3 updates (#170)
Bumps the web-security group with 3 updates in the /src/Web/autopilot-monitor-web directory: [next](https://github.com/vercel/next.js), [brace-expansion](https://github.com/juliangruber/brace-expansion) and [dompurify](https://github.com/cure53/DOMPurify).


Updates `next` from 16.3.5 to 16.3.6
- [Release notes](https://github.com/vercel/next.js/releases)
- [Commits](https://github.com/vercel/next.js/compare/v16.3.5...v16.3.6)

Updates `brace-expansion` from 1.1.18 to 1.1.21
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v1.1.18...v1.1.21)

Updates `dompurify` from 3.4.14 to 3.4.16
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.4.14...3.4.16)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 16.3.6
  dependency-type: direct:production
  dependency-group: web-security
- dependency-name: brace-expansion
  dependency-version: 1.1.21
  dependency-type: indirect
  dependency-group: web-security
- dependency-name: dompurify
  dependency-version: 3.4.16
  dependency-type: indirect
  dependency-group: web-security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-01 11:16:00 +02:00
dependabot[bot] 4b03ba4e19 chore(deps): bump fast-uri (#169)
Bumps the mcp-security group with 1 update in the /src/McpServer/autopilot-monitor-mcp directory: [fast-uri](https://github.com/fastify/fast-uri).


Updates `fast-uri` from 3.1.7 to 3.1.8
- [Release notes](https://github.com/fastify/fast-uri/releases)
- [Commits](https://github.com/fastify/fast-uri/compare/v3.1.7...v3.1.8)

---
updated-dependencies:
- dependency-name: fast-uri
  dependency-version: 3.1.8
  dependency-type: indirect
  dependency-group: mcp-security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-01 11:15:42 +02:00
dependabot[bot] f0aec031f3 chore(deps): bump the actions group with 2 updates (#168)
Bumps the actions group with 2 updates: [github/codeql-action/init](https://github.com/github/codeql-action) and [github/codeql-action/analyze](https://github.com/github/codeql-action).


Updates `github/codeql-action/init` from 4.38.0 to 4.38.2
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/b96794f015dfd88f77b49b1c93e0fa7110f94c63...2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2)

Updates `github/codeql-action/analyze` from 4.38.0 to 4.38.2
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/b96794f015dfd88f77b49b1c93e0fa7110f94c63...2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.38.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.38.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-01 09:28:08 +02:00
Oliver Kieselbach 66208b3767 bump pointer: internal (rule notification placeholders, D-302)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 18:25:11 +02:00
Oliver Kieselbach c60e07dfd4 Rule notifications resolve {{token}} placeholders before they are sent
A stored rule result keeps the rule's template; only the web and the MCP
server resolved it. The notification builders sent the explanation as
stored, so a channel card showed {{reason}}, {{appName}},
{{failedSubcategory}} and {{errorCode}} although the session had recorded
all four values.

- RuleTemplateInterpolator: the backend copy of the resolution, applied in
  BuildRuleFiredAlert and AddRuleResultSections before the text is cut.
  In a notification a list item whose value was not recorded is dropped
  and a token in running text becomes an en dash.
- The cut lands on a line, sentence or word boundary instead of a
  character count; the limits are unchanged.
- tests/fixtures/rule-template-interpolation/cases.json: one case file
  run by the backend, the web and the MCP server.
- The engine's evidence auto-field list is one constant. The web, the MCP
  interpolator and the validate_rule token lint gain timeoutHours, which
  the engine already recorded.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 18:12:02 +02:00
Oliver Kieselbach f564ee6a06 bump pointer: internal (hello wait timeout released)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 15:50:29 +02:00
Oliver Kieselbach ec025686ce bump pointer: internal (hello wait timeout plan, D-301)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
v2.0.1471
2026-09-30 15:38:30 +02:00
Oliver Kieselbach 821c41e2ba Tenant Hello wait timeout up to 1 hour (#167)
* feat: tenant Hello wait timeout up to 1 hour

The "Hello Wait Timeout" setting (30..300 s in the UI) had no effect in the
V2 agent: its only consumer, HelloTracker.StartHelloWaitTimer, has no
production caller, while the decision engine armed a fixed 300 s
hello_safety deadline after the ESP exit and the tracker ran a fixed 300 s
completion timer after the wizard start.

The setting is now the real Hello budget, clamped to 300..3600 s
(HelloWaitTimeout in AutopilotMonitor.Shared). Every value that was valid
before (<= 300, including the old 30 s default) keeps today's 5 minutes.

- Engine: the agent stamps helloWaitTimeoutSeconds on EnrollmentFactsObserved
  (only when > 300), recorded set-once in EnrollmentScenarioObservations.
  All six hello_safety arm sites share one builder with the tenant window;
  a fact that arrives after hello_safety was armed moves it out. The WDP
  backstop is never shorter than the tenant window; the signal census
  surfaces hello_wait_extended.
- Agent: the Hello tracker's wizard completion timer uses the same budget;
  the stall probe skips session_stalled while hello_safety is pending.
- Backend: ValidateModel rejects values outside 300..3600; stored rows are
  read as their effective value, so legacy 30 s rows never block unrelated
  saves or backup reverts. Default 30 -> 300; shared manifest and wire types
  regenerated.
- Web: input 300..3600, bounds pinned against the C# constants.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S17pipjWqjZ8ULAu1JrFyG

* fix: keep the Hello wait's 30 s minimum and default, raise only the maximum

Product decision: the setting keeps its UI contract (30 s minimum and
default, same description); only the maximum moves to 3600 s. Configured
values up to 300 s keep the built-in 5-minute Hello window, larger values
extend it.

- HelloWaitTimeout: MinSeconds/DefaultSeconds 30; BuiltInSeconds 300 is the
  floor of EffectiveSeconds.
- Backend validates only a changed value (30..3600), like the retention cap;
  the read-time normalization is gone again.
- The agent stamps the tenant window only above BuiltInSeconds.
- Web keeps the original text and default; only the maximum and its hint
  change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S17pipjWqjZ8ULAu1JrFyG

* fix: Hello wait default 300 s, stale-fire guard, deferred stall report

Product decision: default 300 s (what V2 has always waited), minimum 30 s
still accepted, maximum 3600 s. Values up to 300 s keep the built-in
5-minute window, which the settings hint now says.

Review follow-ups:
- Engine: a hello_safety fire whose incarnation was replaced (armed due
  later than the fire's due time) is dead-ended, same guard as RealmJoin —
  a late tenant window could otherwise be undercut by the queued fire of
  the built-in deadline. The tenant fact is recorded only when it extends
  the built-in window.
- Stall probe: session_stalled is held back while a tenant-extended Hello
  wait (hello_safety or the WDP backstop) is pending and emitted once it is
  over and the session is still idle; real activity drops it. Default
  tenants never hit the guard.
- Comments: WDP backstop wording, 5-min reference, AgentConfiguration.
- Web pins the default against the shared manifest; tracker constructor
  defaults use HelloWaitTimeout.DefaultSeconds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S17pipjWqjZ8ULAu1JrFyG

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-30 15:36:36 +02:00
Oliver Kieselbach ec3eaa6437 fix(web): sitemap and llms.txt list public pages at their canonical /page/ URL (#166) 2026-09-29 14:13:59 +02:00
Oliver Kieselbach d36c9a659d Merge branch 'main' of https://github.com/okieselbach/AutopilotMonitor 2026-09-29 12:02:55 +02:00