mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-25 05:00:07 +00:00
fd7bf0e7aceac3175fa2eda008d7389fc5432c14
6 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
75c98d131f |
refactor(decisioncore): edge scenarios — hybrid reboot, ESP failure, recovery (M3.5)
Final M3 sub-milestone. Closes the plan's §4 M3 scenario matrix:
Handlers (DecisionEngine.Edge.cs):
- EspResumed mid-ESP reboot. Stage preserved; records
SystemRebootUtc on first observation (hash
stable on repeats).
- EspTerminalFailure Stage=Failed + Outcome=EnrollmentFailed,
deadlines cleared, enrollment_failed event
emitted with reason carried from payload.
Definitive — no classifier re-run.
- SystemRebootObserved records SystemRebootUtc so the WhiteGlove
sealing classifier credits the +15 reboot
weight on the next RunClassifier effect.
Scenario fixtures (committed-anonymized):
- hybrid-reboot-v1.jsonl ESP -> mid-phase reboot -> EspResumed ->
AccountSetup -> Hello -> Desktop ->
Completed. No WhiteGloveSealed path.
- esp-terminal-failure-v1.jsonl ESP -> AccountSetup -> terminal failure
-> Failed / reason=
esp_terminal_failure_account_setup.
Tests (EdgeScenarioTests, 5 new):
- Hybrid reboot preserves stage, records reboot fact, completes
normally without triggering WhiteGlove.
- ESP terminal failure transitions straight to Failed.
- Restart-recovery determinism: replaying the same JSONL twice yields
identical FinalStepHash, Stage, Outcome and transition count.
- Prefix-replay check: truncated log ends in the expected intermediate
stage (simulates crash between signals).
- Global sanity: every committed fixture (all 12) ends in a terminal
stage — regression guard for any future reducer change.
Suite totals: 57 DecisionCore (was 52) / 507 Legacy / 557 Functions =
1121 tests green. All 14+ scenarios from plan §R6 Szenario-Matrix pass
through the reducer with the expected terminal outcome.
This closes M3 (DecisionEngine-Reducer + Classifier-Kernel). M4 wires the
SignalAdapter + EffectRunner + TelemetryTransport in the V2 agent runtime.
Plan: plans/REFACTOR_AGENT_V2.md §4 M3 sub-milestone M3.5 — M3 complete.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
8e4faf4251 |
refactor(decisioncore): WhiteGlove Part 2 + Part2CompletionClassifier + 2 scenarios (M3.4)
Plan §4 M3.4 + plan §2.3 WhiteGlove Part-2 state machine: post-reboot user
sign-in is now a first-class path with a dedicated classifier, a 24h safety
deadline, and an explicit Sealed -> AwaitingUserSignIn -> CompletedPart2 /
Failed progression.
Classifier (WhiteGlovePart2CompletionClassifier : IClassifier):
- Scoring rules NEW (no Legacy equivalent): each of the four Part-2 user
signals (+25) — UserAadSignInComplete, HelloResolvedPart2,
DesktopArrivedPart2, AccountSetupCompletedPart2. All four together hit
the Confirmed threshold (100); missing one drops to Weak (75).
- WhiteGlovePart2CompletionSnapshot implements the new IClassifierSnapshot
interface; existing WhiteGloveSealingSnapshot was retrofit to the same
contract so the harness anti-loop is uniform.
Handlers (DecisionEngine.WhiteGlovePart2.cs):
- SessionRecovered (Shared.cs) now bridges a WhiteGloveSealed state into
WhiteGloveAwaitingUserSignIn and arms the 24h WhiteGlovePart2Safety
deadline on the recovered signal's occurredAt.
- Four Part-2 signal handlers (UserAadSignInComplete, HelloResolvedPart2,
DesktopArrivedPart2, AccountSetupCompletedPart2) record facts + emit a
Part-2 RunClassifier effect; facts arriving outside the AwaitingUserSignIn
stage are recorded but no classifier runs (prevents stray Part-2 verdicts
on non-sealed sessions).
- WhiteGlovePart2Safety deadline handler terminates with Failed /
enrollment_failed reason=part2_user_absent.
- ClassifierVerdictIssued router extended to dispatch on classifier id —
Part-2 verdicts route to ApplyWhiteGlovePart2Verdict; Confirmed triggers
Stage=WhiteGloveCompletedPart2 + Outcome=WhiteGlovePart2Complete +
whiteglove_part2_complete event.
DecisionState: four new SignalFact<DateTime>? fields for the Part-2 signals
(full builder parity).
ClassifierAwareReplayHarness: anti-loop lookup now routes per classifier id
(WhiteGloveSealing <-> WhiteGloveSealing.LastClassifierVerdictId;
Part2Completion <-> WhiteGlovePart2Completion.LastClassifierVerdictId).
Snapshot hashing works through the IClassifierSnapshot interface instead
of a WhiteGloveSealingSnapshot type check.
Scenario fixtures (committed-anonymized):
- whiteglove-part2-happy-v1.jsonl seal Part 1, reboot, 4 Part-2 signals
within minutes -> Confirmed + Part2Complete.
- whiteglove-part2-stuck-v1.jsonl seal Part 1, reboot, 24h passes, safety
deadline fires -> Failed / part2_user_absent.
Tests (3 new in WhiteGlovePart2ScenarioTests):
- Happy terminal state + hypotheses + all four facts + no residual deadlines
- Stuck terminal state + Part-1 Confirmed remains, Part-2 Rejected with reason
- Bridge check: after SessionRecovered(Sealed), Part-2 safety is active
Suite totals: 52 DecisionCore (was 49) / 507 Legacy / 557 Functions.
Plan: plans/REFACTOR_AGENT_V2.md §4 M3 sub-milestone M3.4 + §2.3 Part-2 stages.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
f75a8d4375 |
refactor(decisioncore): WhiteGlove Part 1 handlers + sealing classifier + 4 scenarios (M3.3)
Plan §4 M3.3: the first kernel-service classifier goes live (plan §2.4 L.8),
the effect-based classifier-run contract is wired end-to-end, and the anti-loop
via InputHash is proven by a dedicated fixture.
Classifier (WhiteGloveSealingClassifier : IClassifier):
- Scoring ported 1:1 from Legacy WhiteGloveClassifier (same weights, same
thresholds, same asymmetric-conservative rule: only Confirmed drives the
WhiteGloveSealed stage).
- Positive weights: ShellCoreWhiteGloveSuccess=80, SealingPattern=40,
DeviceOnlyDeployment=15, SystemReboot=15.
- Hard excluders (-100 each): AadJoinedWithUser, DesktopArrived, HelloResolved.
Soft exclude: AccountSetupActivity=-40.
- WhiteGloveSealingSnapshot is the classifier input type and computes a
deterministic SHA256-short InputHash over WG-relevant fields only — so
the anti-loop triggers on meaningful fact changes, not on unrelated state.
Handlers (DecisionEngine.WhiteGlove.cs):
- WhiteGloveShellCoreSuccess records fact; emits RunClassifier effect;
arms ClassifierTick if not already.
- WhiteGloveSealingPatternDetected mirror handler for the IME-pattern path.
- ClassifierVerdictIssued applies the verdict to WhiteGloveSealing
hypothesis; on Confirmed transitions to
WhiteGloveSealed stage +
Outcome=WhiteGlovePart1Sealed and emits
the whiteglove_complete event.
- HandleClassifierTickDeadlineFired (shared router) re-emits RunClassifier
and re-arms itself unless terminal.
ClassifierAwareReplayHarness (tests-only):
- Loops per-step effects: any RunClassifier effect is resolved synchronously
via the registered IClassifier; the verdict is wrapped in a
ClassifierVerdictIssued signal and fed back into Reduce. Anti-loop skips
the call when snapshot hash == state.WhiteGloveSealing.LastClassifierVerdictId.
- Exposes ClassifierRunStats for regression tests.
DecisionState extension: two new SignalFact<bool> fields capture the WG
sightings (ShellCoreWhiteGloveSuccessSeen, WhiteGloveSealingPatternSeen). The
classifier reads them via WhiteGloveSealingSnapshot.
Scenario fixtures (4, committed-anonymized):
- whiteglove-inline-v1.jsonl Confirmed on ShellCore alone (80).
- whiteglove-signal-correlated-v1.jsonl Weak after pattern, ClassifierTick
anti-loop-skipped, Confirmed after
ShellCore escalates the score.
- whiteglove-false-positive-v1.jsonl SealingPattern + late-AADJ hard-
excludes -> Rejected; session still
completes via Classic Hello+Desktop.
- whiteglove-antiloop-v1.jsonl Single pattern + two ticks; runs=1,
skipped_by_antiloop=2.
Tests: 4 scenario tests in WhiteGlovePart1ScenarioTests, all passing.
DecisionCore.Tests: 49 (was 45). Legacy 507 + Functions 557 unchanged.
ReducerFailSafeTests + HarnessTests updated to use AppInstallCompleted as
the still-unhandled sentinel (WhiteGloveShellCoreSuccess is now wired).
Plan: plans/REFACTOR_AGENT_V2.md §4 M3 sub-milestone M3.3 + §2.4 classifier kernel.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
0ebfa2fc3c |
refactor(decisioncore): SelfDeploying + Device-Only handlers + 2 scenarios (M3.2)
SelfDeploying-v1 vertical slice: DeviceSetupProvisioningComplete terminal
handler, DeviceOnlyEspDetection deadline wiring, and the
DeviceOnlyDeployment hypothesis progression UserPresent / DeviceOnly /
Ambiguous expressed via Hypothesis.Reason (plan §2.3).
Handlers (DecisionEngine.SelfDeploying.cs):
- DeviceSetupProvisioningComplete terminal. Cancels all deadlines,
finalizes DeviceOnlyDeployment based on
user-presence facts (AadJoinedWithUser,
HelloResolvedUtc, DesktopArrivedUtc),
raises EnrollmentType to Strong when
no AccountSetup was observed before.
- DeviceOnlyEspDetectionFired hypothesis-only update to
DeviceOnlyDeployment=Strong(DeviceOnly).
Stage unchanged; completion still
requires explicit provisioning signal.
Classic.cs extended:
- First EspPhaseChanged(DeviceSetup) arms the DeviceOnlyEspDetection
deadline (5 min window, plan §2.7).
- EspPhaseChanged(AccountSetup) cancels it — UserDriven-v1 path.
Shared DeadlineFired router routes the deadline to the SelfDeploying body.
Scenario fixtures (tests/fixtures/enrollment-sessions/):
- selfdeploying-happy-v1.jsonl — 3 signals, SkipUserStatusPage
path. Terminal Completed with
DeviceOnly hypothesis confirmed
and no user-presence facts.
- selfdeploying-esp-exit-unknown-v1.jsonl — 4 signals, deadline fires at
T+5m and sets DeviceOnly before
provisioning-complete arrives.
Tests (SelfDeployingScenarioTests, 4 new):
- SelfDeployingHappy terminal state + hypotheses
- SelfDeployingHappy deadline cleanup
- Device-Only ESP-exit-unknown deadline -> provisioning flow
- AccountSetup on the Classic path cancels DeviceOnlyEspDetection
(regression guard — UserDriven should never classify as DeviceOnly)
InternalsVisibleTo added to DecisionCore for DecisionCore.Tests so the
internal DeviceOnlyReasons tokens stay hidden from consumers while tests
assert on them directly.
Suite totals: 45 DecisionCore (was 41) / 507 Legacy / 557 Functions.
Plan: plans/REFACTOR_AGENT_V2.md §4 M3 sub-milestone M3.2.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
0210d42c7f |
refactor(decisioncore): Classic UserDriven-v1 handlers + 3 scenarios (M3.1)
First vertical slice of real reducer behavior: six handlers for the Classic
UserDriven-v1 enrollment flow plus the shared DeadlineFired router, with three
committed-anonymized scenario fixtures driving the proof.
Handlers (DecisionEngine.Classic.cs):
- EspPhaseChanged stage progression DeviceSetup -> AccountSetup;
populates CurrentEnrollmentPhase + DeviceSetupEnteredUtc /
AccountSetupEnteredUtc / FinalizingEnteredUtc facts;
raises EnrollmentType hypothesis to Weak on AccountSetup.
- EspExiting records EspFinalExitUtc; schedules HelloSafety (300 s);
transitions to AwaitingHello and emits ScheduleDeadline.
- HelloResolved records HelloResolvedUtc + HelloOutcome; cancels
HelloSafety; completes session if Desktop already arrived.
- DesktopArrived mirror of HelloResolved; completion when Hello already
resolved.
- ImeUserSessionCompleted raises EnrollmentType hypothesis to Strong; records
matched pattern id.
- AadUserJoinedLate HYPOTHESIS-ONLY (project memory
feedback_aad_joined_late_not_completion). Records
AadJoinedWithUser fact + annotates EnrollmentType reason.
Stage unchanged, no terminal event. Regression guard test
verifies From/To stage equality.
Shared router (DecisionEngine.Shared.cs):
- DeadlineFired dispatches on Payload[deadline]. HelloSafety timeout synthesizes
HelloOutcome=Timeout and drives the same completion path as HelloResolved.
Unknown deadline names cancel the deadline and record a neutral transition —
forward-compat with M3.3 (ClassifierTick) / M3.4 (WhiteGlovePart2Safety).
Constants:
- DeadlineNames enumerates the 7 pflicht-deadlines from plan §2.6.
- SignalPayloadKeys standardizes payload keys used by collectors and the
deadline scheduler.
Scenario harness + fixtures (tests/fixtures/enrollment-sessions/):
- ScenarioTestBase locates repo root and wraps FixtureLoader + ReplayHarness.
- userdriven-happy-v1.jsonl — 7 signals, terminal Completed /
EnrollmentComplete / HelloOutcome=Success.
- userdriven-hello-timeout-v1.jsonl — Desktop arrives before Hello, deadline
fires at T+5m -> HelloOutcome=Timeout,
Completed.
- late-aadj-v1.jsonl — Late-AADJ mid-flight does not complete
prematurely; session still completes
normally via Hello + Desktop.
Tests: 4 scenario tests in ClassicScenarioTests + determinism check.
Total suite: 41 DecisionCore.Tests (was 37 at M3.0) / 507 Legacy unchanged /
557 Functions unchanged.
Plan: plans/REFACTOR_AGENT_V2.md §4 M3 sub-milestone M3.1.
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>
|