mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-23 20:26:10 +00:00
main
10 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
04fae4fe86 |
Web Push channel: alerts to paired phones without a third-party messenger (#177)
* bump pointer: internal (ingest-session-row-reads RELEASED, measurement) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Web Push channel: alerts to paired phones without a third-party messenger (D-327 to D-330) Provider WebhookProviderType.Push = 50 in both channel scopes. It carries no destination; NotificationChannelDispatcher takes a NotificationScope from every caller and the push transport resolves the scope's paired devices at send time (table-backed Admin/Operator, GlobalAdmin with matching identity binding; Viewer and Global Reader never). The receiver never signs in: a signed-in Admin/Operator creates a one-shot pairing code (11 Crockford chars, hashed, 10 min, ETag one-shot, five-failure burn), the phone redeems it anonymously, the portal session confirms. The phone's only credential is the device token in X-Push-Device-Token, good for status, re-subscribe and unpair of its own row (10 calls per minute per device; the anonymous pairing routes 10 per minute per IP). Payloads are RFC 8291 per device (new BCL-only library src/Push with the RFC vector pinned byte for byte) with a VAPID key ring and the kid on every device row; the projection reads an allow-list only (never Sections, DataJson, Failure Reason, Last Failure or the ops message), serial masked, 2 KB. 404/410 mark a device Stale instead of deleting it and the receiver re-arms it on its next open (the same PUT lifts a delivery-failures pause); devices pause when their owner stops signing in (PushOwners stamp in auth/me) through one pause path and resume by themselves; an owner without a stamp is paused, never deleted outright; role loss revokes with a wipe push and deletes the row (there is no Revoked state). PushDevices and PushPairingGrants are credential-bearing: raw-table deny-list, no backup, redacted dependency rows. Receiver app under /push/ (module service worker, Declarative Web Push shape, local history, pairing and status pages, manifest + icons), portal UI (Push provider in the channel editor, pairing dialog with QR code, device lists for tenant and platform scope, "Notify me when done" on the session page — the watch row records the watcher's own scopes, so a Global Admin watching a customer session is notified on the platform-paired phone), 22 catalogued routes, ops events PushDeliveryFailed and PushEndpointRefused (deduplicated per instance), maintenance sweep inside the existing run, settings template. The tenant-scope provider stays Global-Admin-only until the customer release (same ValidateModel gate as Telegram). Backend 7371, library 125, MCP 997, web 2061 tests. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * bump pointer: internal, .claude/commands, infra (push-relay: plan, D-327 to D-330, markers, VAPID generator) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * bump pointer: internal (push-relay: commit step ticked) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Drop sprintf-js from both lockfiles (Dependabot #114, #117) GHSA-hp3w-g68c-fv3c (sprintf-js <= 1.1.3, denial of service through unbounded precision specifiers) has no patched release, so both chains are cut instead. MCP (#117): sprintf-js arrived via @huggingface/transformers -> onnxruntime-node -> global-agent 3 -> roarr. global-agent is only loaded by onnxruntime-node's CUDA install script, which the image never runs (npm ci --ignore-scripts). The override global-agent ^4.1.3 drops roarr; 4.x keeps the bootstrap export that script calls, and onnxruntime-node 1.30 depends on the same range. Rules tooling (#114): ajv-cli 5.0.0 (no release since 2023) pulled js-yaml 3 -> argparse 1 -> sprintf-js. rules/scripts/validate.js now checks the four rule sets against their schemas with ajv (draft 2020-12) and ajv-formats directly, and combine-rules.yml runs it in one step instead of four ajv-cli loops. The lockfile shrinks from 26 to 6 packages; the fast-json-patch override and the legacy-peer-deps .npmrc (only there for ajv-cli's ts-node peer) are gone. Verified: validate.js accepts all 149 rule files plus guardrails.json exactly as ajv-cli did and rejects a corrupted copy (missing field, broken JSON, U+2028 in a guardrail value) with exit 1; clean npm ci + combine.js leave the generated outputs unchanged; MCP build and 997 tests green; zizmor clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * bump pointer: internal, .claude/commands (validate.js replaces ajv-cli: B-gzv, rule-builder fallback) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Bump sharp, proxy-addr and source-map-js past fresh advisories (MCP, Web) - sharp 0.35.4 -> 0.35.5 (GHSA-wq5f-xc86-pv6w, librsvg): the existing sharp override in both projects now floors at ^0.35.5 so the fixed build cannot be undercut by a parent range. - proxy-addr 2.0.7 -> 2.0.8 (GHSA-jqcg-44mw-7w3h, via express; MCP only) and source-map-js 1.2.1 -> 1.2.2 (GHSA-68fv-2mgg-jv7q, via postcss) are lockfile-only bumps inside the ranges their parents declare. No other lockfile entry moved. npm audit in the MCP server is clean. Verified: MCP build and 997 tests green; Web tsc clean, 2061 tests green, next build (static export) succeeds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * bump pointer: internal (push-relay: CORS verified, cert-exclusion prerequisite, EU app facts) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Web: Next.js 16.3.6 -> 16.3.8 (six advisories) 16.3.8 closes GHSA-3w37-wq28-93x7, GHSA-4jqv-mc3x-m676, GHSA-39w2-rjm5-chcv, GHSA-f87g-xv8r-7p7x, GHSA-mcj8-r9mp-w47p and GHSA-cjq9-62q9-8jv4 (affected 16.0.0 - 16.3.7). Under output:"export" the cache, ISR and image-optimization paths never run on the SWA; the dev-server disclosure is local-only. The patch is taken anyway. next, eslint-config-next and @next/bundle-analyzer stay aligned and floor at ^16.3.8; the lockfile is pinned to 16.3.8, not the 16.4.0 minor the caret would resolve to. What npm audit still reports (braces, micromatch, chokidar, fast-glob, postcss-selector-parser) comes through Tailwind 3 and eslint-config-next, build-time only; braces has no fix, the rest needs Tailwind 4 (backlog). Verified: tsc clean, eslint 0 findings, 2061 tests green, next build (16.3.8, 102 static pages) succeeds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * bump pointer: internal (B-dzs lockfile merge note, B-hxz braces chain) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
9f7b070e80 |
chore: remove legacy V1 agent and its backend ingest path
The V1 agent line is retired: no new V1 sessions since 2026-05-09, only orphaned straggler traffic remained on /api/agent/ingest (last seen 2026-06-29, events for long-cleaned-up sessions). Bootstrap/Intune/CI have deployed V2-only since the v2 cutover. Agent: - Delete AutopilotMonitor.Agent, .Agent.Core, .Agent.Core.Tests (projects + sln entries). V2 trio, SummaryDialog, DecisionCore.Tests and V2Isolation.targets stay. Backend: - Relocate the shared statics/DTOs V2 reused from the V1 partials (StampServerFields, SanitizeEventTimestamps, IsMaxLifetimeAgentShutdown, RecalculateAppDurations, EventClassification, AppInstallAggregationState) into EventIngestProcessor; IngestEventsOutput moves next to IngestTelemetryFunction (same namespace, zero ripple). - Delete IngestEventsFunction (route agent/ingest), BootstrapIngestEvents (route bootstrap/ingest), NdjsonParser and their DI registration. EventDataNormalizer stays (used by TelemetryPayloadParser). - Drop both routes from EndpointAccessPolicyCatalog and RequestTelemetryMiddleware.TenantHeaderTrustedPaths. - Retire the V1 update-hash oracle: LatestAgentV1*/LatestBootstrapV1* fields + GetAgentLine case 1 (default arm returns empty hashes, so stragglers gracefully skip the integrity check; ParseAgentMajor keeps its default of 1 on purpose — defaulting to 2 would feed V2 hashes to V1 binaries). TableConfigRepository Store+Map updated in lockstep. - Remove ApiEndpoints.IngestEvents/.BootstrapIngestEvents constants. Tests: NdjsonParserTests deleted; timestamp/critical-path/max-lifetime tests repointed to EventIngestProcessor; the two NDJSON pipeline tests removed (coverage retained by direct-list siblings); catalog/no-store InlineData rows updated. Docs: architecture.md (endpoint tables, ingest flow diagram, solution layout, test matrix), web SectionAgentInternals endpoint tables, build.ps1 help text. Azure: no config change needed — /api/agent is not in the client-cert exclusion paths (agent/ingest was always cert-enforced) and the /api/bootstrap prefix exclusion remains for the surviving bootstrap routes (verified via ARM on autopilotmonitor-api). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
8b7a5f509e |
fix(v2): debrief 7dd4e593 followups + final-status schema 2 + V2 dialog renderer
F3 — SummaryDialog launch crash: switch temp dir from C:\WINDOWS\SystemTemp\ (unreadable for standard users when agent runs as SYSTEM) to flat %ProgramData%\AutopilotMonitor-Summary\ + wipe-on-launch (V1 parity), and grant BUILTIN\Users delete rights so the dialog's --cleanup self-removal works. F4 — Backend phase classification: classify `phase_transition` events (emitted by V2 DecisionEngine for AppsDevice/AppsUser/FinalizingSetup) as phase updates so CurrentPhase advances during App phases. Also force CurrentPhase=Complete on Status=Succeeded to materialise the terminal phase regardless of the carrier event's Phase value (V2 emits enrollment_ complete with Phase=Unknown per feedback_phase_strategy). F5 — App tracking summary covers all phases: ImeLogTracker now snapshots AppPackageState references (not serialized dicts) before _packageStates. Clear() at the AccountSetup transition, and exposes a deduped union GetAllKnownPackageStates() for the termination summary path. Without this, DeviceSetup apps were silently dropped from app_tracking_summary and the SummaryDialog after the phase transition. Schema 2 / V2 dialog — final-status.json now carries schemaVersion=2 plus failureReason, signalTimestamps, and per-app errorPatternId/errorDetail/ errorCode. SummaryDialog branches on schemaVersion: V1 path is the unchanged legacy renderer (deletable when V1 retires), V2 path renders 6 outcome states (Success / PreProvisioningComplete / TimedOut / Failure / Unknown / WhiteGlovePart2), shows a coloured banner with the agent- supplied failure reason, and per-app rows with duration on the right plus the IME-pattern error detail under the app name when an install failed. V1 agent + V1 dialog rendering remain bit-for-bit identical (no schema field → V1 render path). V1 Agent.Core.Tests 507/507, DecisionCore 220/220. Tests: V2.Core 702/702 (+12 schema-2 builder, signal-timestamps, failure- reason, per-app errors, phase-snapshot dedup, launcher path). Backend 736/736. New SummaryDialog.Tests 45/45 (OutcomeMapper + V1/V2 JSON roundtrip + FormatDuration). Build clean (0 warnings). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
d76da2ad75 |
refactor(v2core): M4.0 persistence writers + deadline scheduler skeleton
- TransitionSerializer + StateSerializer in DecisionCore.Serialization (Newtonsoft-ctor-binding, shared between agent writers + backend verifier) - V2.Core.Persistence: SignalLogWriter, JournalWriter (JSONL append-only, WriteThrough+Flush(true) per append — plan L.12 sofort-flush); SnapshotPersistence (SHA256-envelope, tempfile+rename, .quarantine/) - V2.Core.Orchestration: IDeadlineScheduler + DeadlineScheduler (IClock-basiert; past-due fires on ThreadPool; same-name replace; RehydrateFromSnapshot; plan §2.6 / L.7 Timer-Monopol) - V2.Core.Tests (new net48 xUnit project): 28 tests across persistence (roundtrip, monotonicity, tail-corruption tolerance, checksum-mismatch, quarantine) + scheduler (past-due, future, cancel, replace, rehydrate, dispose) - V2-isolation preserved (no reference to Agent.Core) Testsuite: 1121 → 1149 (+28). Foundation for M4.1–M4.5 (Transport, EffectRunner, SignalAdapters, Orchestrator-Wiring, transitional-Cleanup). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
710504549b |
refactor(agent): V2-Agent-Split skeleton + infrastructure copy (M2)
Three new projects as a clean-slate V2 fork of the Legacy Agent:
AutopilotMonitor.Agent.V2 — net48 exe, minimal Program.cs,
buildcounter 2.0.N, version-v2.json
AutopilotMonitor.Agent.V2.Core — net48 library, 94 files copied from
Agent.Core via bulk sed namespace
rewrite; same folder layout
AutopilotMonitor.DecisionCore.Tests — xUnit net8.0 with ReplayHarness
+ 13 smoke/harness tests
V2 isolation is build-time-enforced via V2Isolation.targets imported from
both V2 csproj files — any Legacy ProjectReference fails the build with a
clear error. Grep-verified at commit time: zero `using
AutopilotMonitor.Agent.Core` statements and zero Legacy ProjectReferences
in the V2 tree.
Per plan §2.11, kernel items (CompletionStateMachine, CompletionGuards,
EnrollmentTracker*, Flows/*, WhiteGloveClassifier, WhiteGloveSignals,
EnrollmentStatePersistence) are transitionally retained so the V2 tree
compiles; M4 removes them when SignalAdapters + V2Orchestrator take over.
Per user direction (feedback_v2_kernel_only_refactor): the V2 refactor
replaces only the decision kernel. All peripheral capabilities — gather
rules, analyzers, diagnostics upload, timezone, server-driven actions,
summary dialog launch, env-var resolution, version checks, registry
watchers, network/DO/performance telemetry, self-update, bootstrap→cert
handover, self-destruct — are preserved verbatim via the bulk copy.
Supporting M3 bring-up platform:
- ReplayHarness (empty-stream deterministic, SHA256 hash over terminal
state fields) in DecisionCore.Tests/Harness/
- Fixture scaffold under tests/fixtures/: committed anonymized directory
with commit-policy README, plus gitignored enrollment-sessions-local/
for raw exports
- tools/export-session-fixture.mjs with --help / --dry-run / --validate
modes; real MCP wiring marked TODO(v2-m3)
V2 bootstrap scripts scripts/Bootstrap/Install-AutopilotMonitor-v2(.|-dev).ps1
(committed, pure ASCII verified per feedback_ps1_ascii_only). V2 deployment
scripts under scripts/Deployment/V2/ are gitignored (analog to Legacy).
Test totals at M2 gate: 13 DecisionCore + 507 Agent.Core (unchanged) +
557 Functions (unchanged) = 1077 green.
Plan: plans/REFACTOR_AGENT_V2.md §4 M2 + §2.16 V2-Agent-Split.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
830a27bb70 |
refactor(decisioncore): add DecisionCore shared library scaffolding (M1)
New netstandard2.0 project src/Shared/AutopilotMonitor.DecisionCore/ with 14 scaffolding types across Signals/, State/, Classifiers/, Engine/. Agent.Core and Functions reference the library without call-sites; the full solution builds 0 errors, 0 warnings. DecisionEngine.Reduce is an intentional NotImplementedException stub — M3 fills in the partial-class reducer. Invariants wired into the scaffolding: - Immutable DTOs (sealed + get-only + With-methods) per L.3 - Pflicht-Evidence validation in Evidence ctor per L.5 - KindSchemaVersion enforcement per L.6 - AssemblyVersion 2.0.0.0 as ReducerVersion source per §2.10 Architecture principles L.1–L.18 extracted to .claude/architecture-principles.md as persistent Claude-session context. Plan: plans/REFACTOR_AGENT_V2.md §4 M1. Zero runtime risk. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
7c3d8f54bd | added agent unit tests | ||
|
|
4982ae893d | added optional EnrollmentSummary dialog, better Event Timeline (added search) and Phase Timeline (clickable Phases) | ||
|
|
1f796bf6e3 |
feat: externalize rules to GitHub + API consolidation + preview mode
## Rules as GitHub single source of truth - Add 75 individual JSON rule files (2 gather, 18 analyze, 55 IME patterns) under rules/gather/, rules/analyze/, rules/ime-log-patterns/ - Add JSON Schemas for all three rule types with VS Code IntelliSense support - Add CI combine script (rules/scripts/combine.js) + GitHub Action that validates schemas with ajv-cli and generates rules/dist/ combined files - Convert BuiltIn*.cs from hardcoded C# objects to embedded JSON resource loaders - Add GitHubRuleRepository service to fetch dist/ files from raw.githubusercontent.com - Add ReseedFromGitHubFunction: POST /api/rules/reseed-from-github?type=all|gather|analyze|ime ## IME Log Patterns - Extend ImeLogPattern model with Description and IsBuiltIn properties - Add ImeLogPatterns table + API constants - Add TableStorageService CRUD methods for IME log patterns - Add ImeLogPatternService (CRUD, merge, auto-seed from embedded JSON) - Add ImeLogPatternsFunction: GET/PUT /api/rules/ime-log-patterns (Phase 1: read-only for tenants, Galactic Admin can enable/disable/edit globally) - Add IME Log Patterns management page (/ime-log-patterns) - Wire GetAgentConfigFunction to use ImeLogPatternService instead of static class ## API route consolidation - All rule endpoints now under /api/rules/* for single certificate exclusion path: /api/rules/gather, /api/rules/analyze, /api/rules/ime-log-patterns, /api/rules/reseed-from-github ## Export buttons - Add per-rule and export-all JSON download buttons to gather-rules, analyze-rules, and ime-log-patterns pages ## Admin configuration - Replace old individual reseed buttons with unified "Fetch & Reseed from GitHub" (calls new GitHub endpoint) plus compact individual-type reseed buttons - Add CDN cache hint: GitHub raw.githubusercontent.com caches up to 5 minutes ## Preview mode - ?preview=1 URL param seeds localStorage.previewMode (persists across navigation) - ?preview=0 clears it; toggle in Navbar settings dropdown (indigo, eye icon) - IME Log Patterns nav link gated behind galacticAdminMode OR previewMode - Preview badge shown on nav link when active for normal users ## Tests - Add xUnit test project (net8.0) with 5 tests for embedded resource loading, known IME actions validation, and valid categories check Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
5690620058 | Initial commit |