Audit Phase 6R-AG AH and sharpen scramble successor authority

This commit is contained in:
axiomlogicnexus 2026-05-27 02:33:48 +02:00
parent 0f88d3b301
commit d28366348f
5 changed files with 331 additions and 8 deletions

View file

@ -145,6 +145,27 @@ namespace HyperTwistWhisperCppPhase6RAGTestInternal
SessionState->LastError = TEXT("service-base-url-missing");
}
}
void ForceRetryState(
UHyperTwistTrainingSubsystem* TrainingSubsystem,
const FString& SessionId,
const FString& ErrorText
)
{
if (FHyperTwistTrainingCompanionSpeechSessionState* SessionState =
ResolveActiveSpeechSessionState(TrainingSubsystem))
{
SessionState->bSessionOpen = true;
SessionState->ActiveSessionId = SessionId;
SessionState->OpenedAtUtc = FDateTime::UtcNow().ToIso8601();
SessionState->LastUpdatedAtUtc = SessionState->OpenedAtUtc;
SessionState->SessionConfig = UHyperTwistContractLibrary::MakeSampleSpeechSessionConfig();
SessionState->SessionConfig.SessionId = SessionId;
SessionState->LastError = ErrorText;
SessionState->ServiceHealth.LastError = ErrorText;
SessionState->ServiceHealth.bReady = false;
}
}
}
IMPLEMENT_SIMPLE_AUTOMATION_TEST(
@ -345,4 +366,59 @@ bool FHyperTwistWhisperCppPhase6RAGNativeCaptureRouteWorkflowPreparationStateTes
return true;
}
IMPLEMENT_SIMPLE_AUTOMATION_TEST(
FHyperTwistWhisperCppPhase6RAGNativeCaptureRouteWorkflowRetryStateTest,
"HyperTwist.Permissive.WhisperCpp.Phase6R.AG.NativeCaptureRouteWorkflowRetryState",
EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)
bool FHyperTwistWhisperCppPhase6RAGNativeCaptureRouteWorkflowRetryStateTest::RunTest(
const FString& Parameters
)
{
UHyperTwistTrainingSubsystem* TrainingSubsystem =
HyperTwistWhisperCppPhase6RAGTestInternal::MakeSpeechSubsystem(
TEXT("phase6r-ag-retry-session"),
TEXT("http-sidecar")
);
TestNotNull(TEXT("The speech subsystem must be constructed for the retry workflow test."), TrainingSubsystem);
if (TrainingSubsystem == nullptr)
{
return false;
}
UHyperTwistHttpSpeechClient* HttpSpeechClient =
HyperTwistWhisperCppPhase6RAGTestInternal::ResolveHttpSpeechClient(TrainingSubsystem);
TestNotNull(TEXT("The provider-backed speech client must be available for the retry workflow test."), HttpSpeechClient);
if (HttpSpeechClient == nullptr)
{
return false;
}
HttpSpeechClient->RequestTimeoutSeconds = 0.25f;
HyperTwistWhisperCppPhase6RAGTestInternal::ForceRetryState(
TrainingSubsystem,
TEXT("phase6r-ag-retry-session"),
TEXT("request-failed")
);
TrainingSubsystem->RefreshCompanionSpeechServiceHealthForAutomation();
const FHyperTwistSpeechNativeCaptureRouteWorkflowState& WorkflowState =
TrainingSubsystem->GetActiveCompanionSpeechSessionState().NativeCaptureRouteWorkflowState;
TestTrue(TEXT("The retry-required native capture-route workflow state must remain structurally valid."), WorkflowState.IsStructurallyValid());
TestEqual(TEXT("The retry-required workflow must preserve the retry workflow state id."), WorkflowState.WorkflowStateId, TEXT("capture-route-retry-required"));
TestEqual(TEXT("The retry-required workflow must preserve the retry capture-route posture."), WorkflowState.CaptureRouteStateId, TEXT("route-retry-required"));
TestEqual(TEXT("The retry-required workflow must preserve the retry source kind."), WorkflowState.LatestSourceKind, TEXT("capture-route-retry-required"));
TestFalse(TEXT("The retry-required workflow must clear ownership confirmation."), WorkflowState.bRouteOwnershipConfirmed);
TestFalse(TEXT("The retry-required workflow must block workflow-ready posture."), WorkflowState.bWorkflowReady);
TestTrue(TEXT("The retry-required workflow must surface the retry action."), WorkflowState.bPreparationRetryVisible);
TestEqual(TEXT("The retry-required workflow must retain one workflow entry."), WorkflowState.WorkflowEntryCount, 1);
TestEqual(TEXT("The retry-required workflow must retain one retry entry."), WorkflowState.RouteRetryEntryCount, 1);
TestEqual(TEXT("The retry-required workflow must classify the active issue correctly."), WorkflowState.ActiveIssue.IssueKind, TEXT("capture-route-retry-required"));
TestEqual(TEXT("The retry-required workflow must recommend the bounded retry action."), WorkflowState.ActiveIssue.RecommendedActionId, TEXT("retry-capture-route"));
TestEqual(TEXT("The retry-required workflow must preserve the provider-backed transport failure."), WorkflowState.LastRouteError, TEXT("request-failed"));
return true;
}
#endif

View file

@ -146,6 +146,27 @@ namespace HyperTwistWhisperCppPhase6RAHTestInternal
}
}
void ForceRetryState(
UHyperTwistTrainingSubsystem* TrainingSubsystem,
const FString& SessionId,
const FString& ErrorText
)
{
if (FHyperTwistTrainingCompanionSpeechSessionState* SessionState =
ResolveActiveSpeechSessionState(TrainingSubsystem))
{
SessionState->bSessionOpen = true;
SessionState->ActiveSessionId = SessionId;
SessionState->OpenedAtUtc = FDateTime::UtcNow().ToIso8601();
SessionState->LastUpdatedAtUtc = SessionState->OpenedAtUtc;
SessionState->SessionConfig = UHyperTwistContractLibrary::MakeSampleSpeechSessionConfig();
SessionState->SessionConfig.SessionId = SessionId;
SessionState->LastError = ErrorText;
SessionState->ServiceHealth.LastError = ErrorText;
SessionState->ServiceHealth.bReady = false;
}
}
bool ContainsPanelId(
const TArray<FHyperTwistSpeechShellPanelLayout>& Panels,
const FString& ExpectedPanelId
@ -361,4 +382,55 @@ bool FHyperTwistWhisperCppPhase6RAHNativeCaptureRouteShellPreparationStateTest::
return true;
}
IMPLEMENT_SIMPLE_AUTOMATION_TEST(
FHyperTwistWhisperCppPhase6RAHNativeCaptureRouteShellRetryStateTest,
"HyperTwist.Permissive.WhisperCpp.Phase6R.AH.NativeCaptureRouteShellRetryState",
EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)
bool FHyperTwistWhisperCppPhase6RAHNativeCaptureRouteShellRetryStateTest::RunTest(
const FString& Parameters
)
{
UHyperTwistTrainingSubsystem* TrainingSubsystem =
HyperTwistWhisperCppPhase6RAHTestInternal::MakeSpeechSubsystem(
TEXT("phase6r-ah-retry-session"),
TEXT("http-sidecar")
);
TestNotNull(TEXT("The speech subsystem must be constructed for the retry shell test."), TrainingSubsystem);
if (TrainingSubsystem == nullptr)
{
return false;
}
UHyperTwistHttpSpeechClient* HttpSpeechClient =
HyperTwistWhisperCppPhase6RAHTestInternal::ResolveHttpSpeechClient(TrainingSubsystem);
TestNotNull(TEXT("The provider-backed speech client must be available for the retry shell test."), HttpSpeechClient);
if (HttpSpeechClient == nullptr)
{
return false;
}
HttpSpeechClient->RequestTimeoutSeconds = 0.25f;
HyperTwistWhisperCppPhase6RAHTestInternal::ForceRetryState(
TrainingSubsystem,
TEXT("phase6r-ah-retry-session"),
TEXT("request-failed")
);
TrainingSubsystem->RefreshCompanionSpeechServiceHealthForAutomation();
const FHyperTwistSpeechNativeCaptureRouteShellState& ShellState =
TrainingSubsystem->GetActiveCompanionSpeechSessionState().NativeCaptureRouteShellState;
TestTrue(TEXT("The retry-required native capture-route shell state must remain structurally valid."), ShellState.IsStructurallyValid());
TestEqual(TEXT("The shell must preserve the retry workflow state id."), ShellState.WorkflowStateId, TEXT("capture-route-retry-required"));
TestEqual(TEXT("The shell must preserve the retry capture-route posture."), ShellState.CaptureRouteStateId, TEXT("route-retry-required"));
TestTrue(TEXT("The shell must surface the preparation card for route retry."), ShellState.bPreparationCardVisible);
TestTrue(TEXT("The shell must surface the retry action."), ShellState.bPreparationRetryVisible);
TestEqual(TEXT("The shell must classify the active issue correctly."), ShellState.ActiveIssue.IssueKind, TEXT("capture-route-retry-required"));
TestTrue(TEXT("The shell must preserve the bounded retry action."), ShellState.AvailableActionIds.Contains(TEXT("retry-capture-route")));
TestEqual(TEXT("The shell must preserve the provider-backed transport failure."), ShellState.LastRouteError, TEXT("request-failed"));
return true;
}
#endif

View file

@ -0,0 +1,162 @@
# HyperTwist Cubing Scramble Successor Surfaces Deep-Source Evaluation - 2026-05-27
## Status
This document is the source-backed evaluation note for the retained cubing
scramble successor surfaces:
- `cubing/mark3`
- `cubing/scramble.cubing.net`
- `cubing/scramble-display`
It answers one narrow question:
- do these successor repos displace the already retained `cubing/cubing.js`
and `cubing/twisty.js` ownership lanes for scramble generation or
scramble-operator shells
They do not.
## Source basis
- `C:\Workspaces\HyperTwist\mirrors\permissive\cubing\cubing.js\src\cubing\scramble\index.ts`
- `C:\Workspaces\HyperTwist\mirrors\permissive\cubing\cubing.js\src\cubing\search\cubing-private.ts`
- `C:\Workspaces\HyperTwist\mirrors\permissive\cubing\cubing.js\src\cubing\search\outside.ts`
- `C:\Workspaces\HyperTwist\mirrors\restrictive\cubing\mark3\README.md`
- `C:\Workspaces\HyperTwist\mirrors\restrictive\cubing\mark3\package.json`
- `C:\Workspaces\HyperTwist\mirrors\restrictive\cubing\mark3\src\scramble-generation\index.ts`
- `C:\Workspaces\HyperTwist\mirrors\restrictive\cubing\mark3\src\fixtures\testCompetitionScramblesSpec.ts`
- `C:\Workspaces\HyperTwist\mirrors\restrictive\cubing\scramble.cubing.net\README.md`
- `C:\Workspaces\HyperTwist\mirrors\restrictive\cubing\scramble.cubing.net\package.json`
- `C:\Workspaces\HyperTwist\mirrors\restrictive\cubing\scramble.cubing.net\src\scramble.ts`
- `C:\Workspaces\HyperTwist\mirrors\restrictive\cubing\scramble-display\README.md`
- `C:\Workspaces\HyperTwist\mirrors\restrictive\cubing\scramble-display\src\scramble-display\ScrambleDisplay.ts`
## Slice-local verdict
| Slice | Primary authority | Secondary value kept | Route | Width | Result |
|---|---|---|---|---|---|
| Random-state scramble engine and event scramble API | `cubing/cubing.js` | `cubing/mark3`, `cubing/scramble.cubing.net` | existing retained route | existing retained width | unchanged |
| Seeded competition, round, set, and attempt scramble workflow expectations | `cubing/cubing.js` for the engine contract | `cubing/mark3` as fixture/workflow adjunct | `R3` for `mark3` | `F2` | keep `mark3` as bounded adjunct only |
| Public scramble operator shell behavior | `cubing/cubing.js` + `cubing/twisty.js` for engine and visualization seams | `cubing/scramble.cubing.net` as operator-shell adjunct | `R3` for `scramble.cubing.net` | `F2` | keep as bounded shell reference only |
| Lightweight scramble display wrapper behavior | `cubing/twisty.js` | `cubing/scramble-display` as comparison/reference wrapper | `R3` for `scramble-display` | `F2` | keep as comparison surface only |
## Why the ownership does not flip
### `cubing/mark3`
`mark3` does not replace `cubing/cubing.js` for scramble generation.
The current source imports `randomScrambleForEvent` from `cubing/scramble` and
uses it directly inside the round/set/attempt loop. The `README.md` also marks
seed derivation as future work, and `src/scramble-generation/index.ts` still
contains a `TODO` comment for that derivation path.
Retained value that survives:
- competition/WCIF-shaped scramble generation workflow
- round/set/attempt traversal shape
- seeded derivation intent and fixture framing
Value that does not survive as owner displacement:
- the actual scramble engine
- event scramble correctness ownership
- scramble API ownership
Working classification:
- `A2` adjunct donor for competition scramble workflow expectations
- `R3` clean-room route because the row remains restrictive custody
- `F2` only; no broad scramble-engine promotion
### `cubing/scramble.cubing.net`
`scramble.cubing.net` does not replace `cubing/cubing.js` or `cubing/twisty.js`
for the underlying scramble or visualization seams.
The current source imports `randomScrambleForEvent` from `cubing/scramble`,
imports `cubing/twisty`, binds event selection and URL parameters in the shell,
and uses those existing seams to present a public scramble operator surface.
Retained value that survives:
- event-selection behavior
- refresh/rescramble workflow
- URL-state and view-option behavior
- copy-to-clipboard and lightweight operator-shell posture
Value that does not survive as owner displacement:
- scramble engine ownership
- puzzle visualization ownership
- general command-surface ownership for HyperTwist
Working classification:
- `A2` adjunct donor for public scramble operator-shell behavior
- `R3` clean-room route because the row remains restrictive custody
- `F2` only; no shell-family widening by default
### `cubing/scramble-display`
`scramble-display` is a convenience wrapper above `cubing/twisty`, not a new
display owner lane.
The current custom element maps `event` to a `TwistyPlayer`, applies
visualization and background convenience properties, and forwards scramble text
into the already retained visualization seam.
Working classification:
- `A3` reference authority for wrapper convenience only
- `R3` clean-room route because the row remains restrictive custody
- `F2` only; comparison surface, not owner displacement
## Propagation result
### Feature registry
Updated.
The registry now keeps a narrow retained row for seeded competition scramble
workflow and lightweight scramble-operator-shell adjuncts while preserving
`cubing/cubing.js` and `cubing/twisty.js` as the deeper owners.
### Cross-lane doctrine
No doctrine wording change was needed.
The current doctrine already covers this outcome:
- later repos only displace the exact stronger slice
- partial successors stay bounded adjuncts or references
### Retroactive backfill
No selective reopening of earlier packet authority was required.
Reason:
- no earlier `A1` winner was displaced
- this pass only sharpened successor-row interpretation and retained adjunct
value
### Skillization
No doctrine or `SKILLS.md` change was required.
Reason:
- these repos do not create a first-party HyperTwist command surface
- they do not justify a live skill family by themselves
- any future scramble helper remains command-contract pending until a
first-party scramble command exists
### Legal evidence
No custody or license-status change occurred in this pass.
The legal tracker and manifest rows were sharpened to reflect the source-backed
upper-surface split, and the generated legal-evidence bundle remained a
verification surface rather than a changed policy surface.

View file

@ -750,7 +750,7 @@ Current licensing judgment:
- the checked `package.json` does not declare a repo license
- treat the row as restrictive custody and `license-missing`
- direct donor use is not cleared
- retain as a scramble-generation clean-room candidate only
- retain as a restrictive upper-surface adjunct only
Source basis:
@ -769,10 +769,13 @@ Practical obligations:
Approved working posture:
- retain as a scramble-generation architecture reference and clean-room
candidate only
- use it for source inspection, seeded workflow reference, and independently
owned reimplementation planning
- retain as a seeded competition / round / attempt workflow adjunct above the
already retained `cubing/cubing.js` scramble engine
- use it for source inspection, WCIF-shaped fixture comparison, and
independently owned reimplementation planning
- do not treat it as scramble-engine ownership, because the current source
delegates actual scramble generation to `cubing/scramble` and still leaves
seed derivation as `TODO`
- do not widen from the mirror as a normal permissive donor lane
### `cubing/scramble.cubing.net`
@ -810,9 +813,14 @@ Practical obligations:
Approved working posture:
- retain as a scramble-webapp behavior reference and clean-room candidate only
- retain as a public scramble operator-shell adjunct above the already retained
`cubing/cubing.js` and `cubing/twisty.js` seams
- use it for source inspection, event-selection UX reference, refresh-workflow
comparison, and independently owned reimplementation planning
comparison, URL-state behavior, and independently owned reimplementation
planning
- do not treat it as scramble-engine or visualization ownership, because the
current source imports `randomScrambleForEvent` from `cubing/scramble` and
uses `cubing/twisty` for the player shell
- do not widen from the mirror as a normal permissive or direct-integration
lane
@ -848,7 +856,11 @@ Practical obligations:
Approved working posture:
- retain as a scramble-visualization comparison surface only
- retain as a scramble-display comparison surface only
- use it as a wrapper-convenience reference above the already retained
`cubing/twisty.js` visualization seam
- do not treat it as a new visualization owner lane, because the current
custom element is a thin `TwistyPlayer` wrapper
- use it for source inspection, display-shell behavior reference, and bounded
clean-room planning if a first-party equivalent is ever needed
- do not widen from the mirror as a normal permissive donor lane

View file

@ -150,6 +150,7 @@ repo.
|---|---|---|---|
| Native puzzle-state runtime | Implemented now | first-party runtime + landed donor packets | Core product identity. |
| Classic-cubing semantic/runtime adapter | Implemented now | landed `cubing/cubing.js` packet | Live adapter family. |
| Seeded competition scramble workflow and lightweight scramble-operator shell adjuncts | Deep-source grounded retained | `cubing/cubing.js` retained lane + `cubing/mark3` / `cubing/scramble.cubing.net` successor evaluation | Source-backed successor surfaces sharpen competition-spec workflow and operator-shell expectations above the retained scramble and visualization seams, but they do not displace `cubing/cubing.js` or `cubing/twisty.js`; `scramble-display` remains comparison-only. |
| Replay shell and timeline | Implemented now | landed `cubing/twisty.js` bounded packets | Replay/runtime viewer family is real. |
| Algorithm/training semantic lane | Implemented now | landed `cubing/alg.js` bounded packets | Semantic/training contract is real. |
| Hyper puzzle catalog | Implemented now | `Hyperspeedcube` bounded packet | Current realized hyper-puzzle entry slice. |