mirror of
https://github.com/saymrwulf/BraiinsRatchet.git
synced 2026-05-14 20:37:52 +00:00
Add app reality mirror layer
This commit is contained in:
parent
2c3308a69a
commit
a77493fb3f
11 changed files with 620 additions and 5 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -6,6 +6,7 @@ __pycache__/
|
||||||
data/*.sqlite
|
data/*.sqlite
|
||||||
data/*.sqlite-shm
|
data/*.sqlite-shm
|
||||||
data/*.sqlite-wal
|
data/*.sqlite-wal
|
||||||
|
data/app_visual_state.*
|
||||||
data/raw/
|
data/raw/
|
||||||
*.log
|
*.log
|
||||||
macos/BraiinsRatchet/.build/
|
macos/BraiinsRatchet/.build/
|
||||||
|
|
|
||||||
13
README.md
13
README.md
|
|
@ -46,6 +46,19 @@ This builds `macos/build/Braiins Ratchet.app`, closes any stale `BraiinsRatchetM
|
||||||
|
|
||||||
The app is a native Tahoe Flight Deck: animated hashfield background, real SwiftUI Liquid Glass controls, Hashflow, Ratchet, Bid Lab, Exposure, and Evidence. The design rationale is in `docs/APP_DESIGN_RESEARCH.md`.
|
The app is a native Tahoe Flight Deck: animated hashfield background, real SwiftUI Liquid Glass controls, Hashflow, Ratchet, Bid Lab, Exposure, and Evidence. The design rationale is in `docs/APP_DESIGN_RESEARCH.md`.
|
||||||
|
|
||||||
|
The app also has a `Reality Mirror` self-reflection layer. It writes the exact semantic state the SwiftUI app believes it is showing to:
|
||||||
|
|
||||||
|
```text
|
||||||
|
data/app_visual_state.md
|
||||||
|
data/app_visual_state.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Print the latest mirror snapshot:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/ratchet mirror
|
||||||
|
```
|
||||||
|
|
||||||
Advanced fallback for a 6-hour CLI monitoring session:
|
Advanced fallback for a 6-hour CLI monitoring session:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,20 @@ The app is organized as:
|
||||||
4. `Bid Lab`: shadow order, expected net, breakeven, and loss boundary.
|
4. `Bid Lab`: shadow order, expected net, breakeven, and loss boundary.
|
||||||
5. `Exposure`: record or close manually executed Braiins exposure.
|
5. `Exposure`: record or close manually executed Braiins exposure.
|
||||||
6. `Evidence`: raw cockpit, report, and ledger artifacts for diagnostics.
|
6. `Evidence`: raw cockpit, report, and ledger artifacts for diagnostics.
|
||||||
|
7. `Reality Mirror`: self-reflective BED view that shows what the app believes it is rendering right now.
|
||||||
|
|
||||||
|
The small `Reality Mirror` HUD writes the current visual/operator truth to:
|
||||||
|
|
||||||
|
```text
|
||||||
|
data/app_visual_state.md
|
||||||
|
data/app_visual_state.json
|
||||||
|
```
|
||||||
|
|
||||||
|
If you ask for help, this file is the fastest way to show the exact app state instead of describing it from memory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/ratchet mirror
|
||||||
|
```
|
||||||
|
|
||||||
## Research Pathway
|
## Research Pathway
|
||||||
|
|
||||||
|
|
@ -140,6 +154,7 @@ Use these only if the native app cannot be opened or you are debugging:
|
||||||
./scripts/ratchet position list
|
./scripts/ratchet position list
|
||||||
./scripts/ratchet report
|
./scripts/ratchet report
|
||||||
./scripts/ratchet experiments
|
./scripts/ratchet experiments
|
||||||
|
./scripts/ratchet mirror
|
||||||
./scripts/ratchet guide
|
./scripts/ratchet guide
|
||||||
./scripts/ratchet operator-guide
|
./scripts/ratchet operator-guide
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ Use `./scripts/ratchet guide` for the user-facing operating story.
|
||||||
|
|
||||||
Use `./scripts/ratchet operator-guide` for architecture, installation, migration, backup, recovery, and diagnostics.
|
Use `./scripts/ratchet operator-guide` for architecture, installation, migration, backup, recovery, and diagnostics.
|
||||||
|
|
||||||
|
Use `./scripts/ratchet mirror` to print the native app's latest self-written visual-state snapshot from `data/app_visual_state.md`.
|
||||||
|
|
||||||
The raw Python CLI is documented below for debugging and development.
|
The raw Python CLI is documented below for debugging and development.
|
||||||
|
|
||||||
All raw commands should be run from the repository root.
|
All raw commands should be run from the repository root.
|
||||||
|
|
@ -50,6 +52,16 @@ These are wrapper commands, not raw Python subcommands:
|
||||||
|
|
||||||
`operator-guide` prints `docs/OPERATOR_GUIDE.md`.
|
`operator-guide` prints `docs/OPERATOR_GUIDE.md`.
|
||||||
|
|
||||||
|
## Wrapper Reality Mirror Command
|
||||||
|
|
||||||
|
This is a wrapper command, not a raw Python subcommand:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/ratchet mirror
|
||||||
|
```
|
||||||
|
|
||||||
|
It prints `data/app_visual_state.md`, which is written by the SwiftUI app whenever it refreshes state or changes visible sections. If no snapshot exists yet, open the app with `./scripts/ratchet app` and refresh or open `Reality Mirror`.
|
||||||
|
|
||||||
## `pipeline`
|
## `pipeline`
|
||||||
|
|
||||||
Prints a monitor-only automation proposal and asks for `yes` or `no`.
|
Prints a monitor-only automation proposal and asks for `yes` or `no`.
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,8 @@ The current stack is:
|
||||||
6. SQLite durable state at `data/ratchet.sqlite`.
|
6. SQLite durable state at `data/ratchet.sqlite`.
|
||||||
7. Markdown evidence reports under `reports/`.
|
7. Markdown evidence reports under `reports/`.
|
||||||
8. Bash launchers in `scripts/`.
|
8. Bash launchers in `scripts/`.
|
||||||
9. Git and GitHub on branch `master`.
|
9. SwiftUI self-reflection snapshots at `data/app_visual_state.md` and `data/app_visual_state.json`.
|
||||||
|
10. Git and GitHub on branch `master`.
|
||||||
|
|
||||||
### Runtime Layers
|
### Runtime Layers
|
||||||
|
|
||||||
|
|
@ -71,6 +72,10 @@ Layer 6 is the background engine.
|
||||||
|
|
||||||
`src/braiins_ratchet/engine.py` starts a detached monitor-only supervisor, writes `data/supervisor.pid`, and logs to `logs/supervisor.log`.
|
`src/braiins_ratchet/engine.py` starts a detached monitor-only supervisor, writes `data/supervisor.pid`, and logs to `logs/supervisor.log`.
|
||||||
|
|
||||||
|
Layer 7 is the visual self-reflection layer.
|
||||||
|
|
||||||
|
The SwiftUI app renders a `Reality Mirror` HUD and tab. It writes the semantic state it believes it is showing to `data/app_visual_state.md` and `data/app_visual_state.json`. This is not screenshot OCR; it is the app's own rendered-state ledger.
|
||||||
|
|
||||||
### Data Flow
|
### Data Flow
|
||||||
|
|
||||||
Normal data flow:
|
Normal data flow:
|
||||||
|
|
@ -105,8 +110,10 @@ Operational files:
|
||||||
1. `data/supervisor.pid`: PID for the background engine.
|
1. `data/supervisor.pid`: PID for the background engine.
|
||||||
2. `logs/supervisor.log`: background engine output.
|
2. `logs/supervisor.log`: background engine output.
|
||||||
3. `reports/ACTIVE_WATCH.json`: marker for a running watch.
|
3. `reports/ACTIVE_WATCH.json`: marker for a running watch.
|
||||||
4. `.venv`: local Python environment, disposable.
|
4. `data/app_visual_state.md`: latest human-readable visual self-reflection snapshot.
|
||||||
5. `macos/build/Braiins Ratchet.app`: generated app bundle, disposable.
|
5. `data/app_visual_state.json`: latest machine-readable visual self-reflection snapshot.
|
||||||
|
6. `.venv`: local Python environment, disposable.
|
||||||
|
7. `macos/build/Braiins Ratchet.app`: generated app bundle, disposable.
|
||||||
|
|
||||||
Source files:
|
Source files:
|
||||||
|
|
||||||
|
|
@ -559,6 +566,12 @@ Check app state:
|
||||||
./scripts/ratchet app-state
|
./scripts/ratchet app-state
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Check what the visible app surface believes it is showing:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/ratchet mirror
|
||||||
|
```
|
||||||
|
|
||||||
Check latest plain report:
|
Check latest plain report:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
|
||||||
|
|
@ -73,9 +73,44 @@ The normal app tabs are:
|
||||||
4. `Bid Lab`: shadow order, breakeven, expected net, and loss budget.
|
4. `Bid Lab`: shadow order, breakeven, expected net, and loss budget.
|
||||||
5. `Exposure`: manual Braiins position recorder.
|
5. `Exposure`: manual Braiins position recorder.
|
||||||
6. `Evidence`: raw reports and diagnostic text.
|
6. `Evidence`: raw reports and diagnostic text.
|
||||||
|
7. `Reality Mirror`: the app's self-reflective BED view.
|
||||||
|
|
||||||
If you are unsure, stay on `Flight Deck`.
|
If you are unsure, stay on `Flight Deck`.
|
||||||
|
|
||||||
|
## Reality Mirror
|
||||||
|
|
||||||
|
The `Reality Mirror` is the app looking at itself.
|
||||||
|
|
||||||
|
BED means `Backstage Evidence Deck`.
|
||||||
|
|
||||||
|
It exists because generic advice is not enough. The app writes what it believes it is rendering right now:
|
||||||
|
|
||||||
|
1. Visible section.
|
||||||
|
2. Giant decision word.
|
||||||
|
3. Control owner.
|
||||||
|
4. Next action.
|
||||||
|
5. Engine state.
|
||||||
|
6. Strategy action.
|
||||||
|
7. Braiins freshness.
|
||||||
|
8. Active watch, cooldown, or manual exposure.
|
||||||
|
9. Buttons it believes are visible.
|
||||||
|
10. Operator truths for the current state.
|
||||||
|
|
||||||
|
The files are:
|
||||||
|
|
||||||
|
```text
|
||||||
|
data/app_visual_state.md
|
||||||
|
data/app_visual_state.json
|
||||||
|
```
|
||||||
|
|
||||||
|
If you ask for help, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/ratchet mirror
|
||||||
|
```
|
||||||
|
|
||||||
|
That prints the latest self-written visual state, so the helper can reason about what is actually on your app surface.
|
||||||
|
|
||||||
## Flight Deck Reading Order
|
## Flight Deck Reading Order
|
||||||
|
|
||||||
Read the screen in this order every time:
|
Read the screen in this order every time:
|
||||||
|
|
@ -333,8 +368,9 @@ Use this order:
|
||||||
2. `Ratchet`: where the experiment is in the loop.
|
2. `Ratchet`: where the experiment is in the loop.
|
||||||
3. `Bid Lab`: why the current proposal exists.
|
3. `Bid Lab`: why the current proposal exists.
|
||||||
4. `Exposure`: whether real money blocks new experiments.
|
4. `Exposure`: whether real money blocks new experiments.
|
||||||
5. `Evidence`: raw report and ledger.
|
5. `Reality Mirror`: what the app believes it is showing right now.
|
||||||
6. `docs/OPERATOR_GUIDE.md`: installation, recovery, migration, and diagnostics.
|
6. `Evidence`: raw report and ledger.
|
||||||
|
7. `docs/OPERATOR_GUIDE.md`: installation, recovery, migration, and diagnostics.
|
||||||
|
|
||||||
## Glossary
|
## Glossary
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ This builds `macos/build/Braiins Ratchet.app`, closes any stale `BraiinsRatchetM
|
||||||
- Forever Engine controls for the monitor-only background lifecycle.
|
- Forever Engine controls for the monitor-only background lifecycle.
|
||||||
- Manual exposure recording and closing controls.
|
- Manual exposure recording and closing controls.
|
||||||
- Evidence view for raw artifacts and backend diagnostics.
|
- Evidence view for raw artifacts and backend diagnostics.
|
||||||
|
- Reality Mirror BED layer plus `data/app_visual_state.md/json` self-reflection snapshots.
|
||||||
- Monitor-only. It never places Braiins orders.
|
- Monitor-only. It never places Braiins orders.
|
||||||
|
|
||||||
## Product Direction
|
## Product Direction
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,17 @@ final class RatchetStore: ObservableObject {
|
||||||
closePositionId = ""
|
closePositionId = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writeRealitySnapshot(section: AppSection?) {
|
||||||
|
let reality = RenderedReality.make(
|
||||||
|
section: section ?? .deck,
|
||||||
|
appState: appState,
|
||||||
|
isWorking: isWorking,
|
||||||
|
operation: operation,
|
||||||
|
errorMessage: errorMessage
|
||||||
|
)
|
||||||
|
RealitySnapshotWriter.write(reality)
|
||||||
|
}
|
||||||
|
|
||||||
private func run(label: String, arguments: [String], refreshAfterwards: Bool) async {
|
private func run(label: String, arguments: [String], refreshAfterwards: Bool) async {
|
||||||
operation = label
|
operation = label
|
||||||
rawTitle = label
|
rawTitle = label
|
||||||
|
|
@ -135,12 +146,22 @@ struct FlightDeckApp: View {
|
||||||
root
|
root
|
||||||
.task {
|
.task {
|
||||||
await store.refresh()
|
await store.refresh()
|
||||||
|
store.writeRealitySnapshot(section: selection)
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
withAnimation(.easeInOut(duration: 4.8).repeatForever(autoreverses: true)) {
|
withAnimation(.easeInOut(duration: 4.8).repeatForever(autoreverses: true)) {
|
||||||
pulse = true
|
pulse = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.onChange(of: selection) { _, newValue in
|
||||||
|
store.writeRealitySnapshot(section: newValue)
|
||||||
|
}
|
||||||
|
.onChange(of: store.appState?.generatedAt) { _, _ in
|
||||||
|
store.writeRealitySnapshot(section: selection)
|
||||||
|
}
|
||||||
|
.onChange(of: store.operation) { _, _ in
|
||||||
|
store.writeRealitySnapshot(section: selection)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var root: some View {
|
private var root: some View {
|
||||||
|
|
@ -158,6 +179,17 @@ struct FlightDeckApp: View {
|
||||||
selectedView
|
selectedView
|
||||||
.safeAreaPadding(.horizontal, 30)
|
.safeAreaPadding(.horizontal, 30)
|
||||||
.safeAreaPadding(.vertical, 24)
|
.safeAreaPadding(.vertical, 24)
|
||||||
|
VStack {
|
||||||
|
Spacer()
|
||||||
|
HStack {
|
||||||
|
Spacer()
|
||||||
|
RealityHUD(store: store, section: selection ?? .deck) {
|
||||||
|
selection = .mirror
|
||||||
|
}
|
||||||
|
.padding(.trailing, 24)
|
||||||
|
.padding(.bottom, 20)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.toolbar { toolbarContent }
|
.toolbar { toolbarContent }
|
||||||
.searchable(text: $store.query, placement: .toolbar, prompt: "Search reports, prices, OCEAN, Braiins")
|
.searchable(text: $store.query, placement: .toolbar, prompt: "Search reports, prices, OCEAN, Braiins")
|
||||||
|
|
@ -218,6 +250,8 @@ struct FlightDeckApp: View {
|
||||||
ExposureView(store: store)
|
ExposureView(store: store)
|
||||||
case .vault:
|
case .vault:
|
||||||
EvidenceVaultView(store: store)
|
EvidenceVaultView(store: store)
|
||||||
|
case .mirror:
|
||||||
|
RealityMirrorView(store: store, section: selection ?? .mirror)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -229,6 +263,7 @@ enum AppSection: String, CaseIterable, Identifiable {
|
||||||
case bidlab
|
case bidlab
|
||||||
case exposure
|
case exposure
|
||||||
case vault
|
case vault
|
||||||
|
case mirror
|
||||||
|
|
||||||
var id: String { rawValue }
|
var id: String { rawValue }
|
||||||
|
|
||||||
|
|
@ -240,6 +275,7 @@ enum AppSection: String, CaseIterable, Identifiable {
|
||||||
case .bidlab: "Bid Lab"
|
case .bidlab: "Bid Lab"
|
||||||
case .exposure: "Exposure"
|
case .exposure: "Exposure"
|
||||||
case .vault: "Evidence"
|
case .vault: "Evidence"
|
||||||
|
case .mirror: "Reality Mirror"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,6 +287,7 @@ enum AppSection: String, CaseIterable, Identifiable {
|
||||||
case .bidlab: "shadow order optics"
|
case .bidlab: "shadow order optics"
|
||||||
case .exposure: "manual position lock"
|
case .exposure: "manual position lock"
|
||||||
case .vault: "reports and raw state"
|
case .vault: "reports and raw state"
|
||||||
|
case .mirror: "BED: app sees itself"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -262,6 +299,7 @@ enum AppSection: String, CaseIterable, Identifiable {
|
||||||
case .bidlab: "slider.horizontal.3"
|
case .bidlab: "slider.horizontal.3"
|
||||||
case .exposure: "lock.shield"
|
case .exposure: "lock.shield"
|
||||||
case .vault: "archivebox"
|
case .vault: "archivebox"
|
||||||
|
case .mirror: "eye.square"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1089,6 +1127,156 @@ struct EvidenceVaultView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct RealityHUD: View {
|
||||||
|
@ObservedObject var store: RatchetStore
|
||||||
|
let section: AppSection
|
||||||
|
let openMirror: () -> Void
|
||||||
|
|
||||||
|
private var reality: RenderedReality {
|
||||||
|
RenderedReality.make(
|
||||||
|
section: section,
|
||||||
|
appState: store.appState,
|
||||||
|
isWorking: store.isWorking,
|
||||||
|
operation: store.operation,
|
||||||
|
errorMessage: store.errorMessage
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
LiquidGlassSurface(tint: .white.opacity(0.10), cornerRadius: 24) {
|
||||||
|
VStack(alignment: .leading, spacing: 10) {
|
||||||
|
HStack {
|
||||||
|
Label("Reality Mirror", systemImage: "eye")
|
||||||
|
.font(.caption.weight(.heavy))
|
||||||
|
.textCase(.uppercase)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
Spacer()
|
||||||
|
Button("Open") {
|
||||||
|
openMirror()
|
||||||
|
}
|
||||||
|
.buttonStyle(.glass)
|
||||||
|
.controlSize(.small)
|
||||||
|
}
|
||||||
|
Text(reality.decisionTitle)
|
||||||
|
.font(.title2.weight(.black))
|
||||||
|
.foregroundStyle(reality.decisionTint)
|
||||||
|
Text(reality.currentInstruction)
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
.lineLimit(3)
|
||||||
|
Text("writes data/app_visual_state.md")
|
||||||
|
.font(.caption2.monospaced())
|
||||||
|
.foregroundStyle(.tertiary)
|
||||||
|
}
|
||||||
|
.padding(14)
|
||||||
|
.frame(width: 330, alignment: .leading)
|
||||||
|
}
|
||||||
|
.accessibilityLabel("Reality Mirror heads-up display, current decision \(reality.decisionTitle)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RealityMirrorView: View {
|
||||||
|
@ObservedObject var store: RatchetStore
|
||||||
|
let section: AppSection
|
||||||
|
|
||||||
|
private var reality: RenderedReality {
|
||||||
|
RenderedReality.make(
|
||||||
|
section: section,
|
||||||
|
appState: store.appState,
|
||||||
|
isWorking: store.isWorking,
|
||||||
|
operation: store.operation,
|
||||||
|
errorMessage: store.errorMessage
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ScrollView {
|
||||||
|
VStack(alignment: .leading, spacing: 22) {
|
||||||
|
SectionHeader("Reality Mirror", "BED: Backstage Evidence Deck. This is the app reflecting the concrete state it is rendering now, not generic advice.")
|
||||||
|
|
||||||
|
HStack(alignment: .top, spacing: 18) {
|
||||||
|
LiquidGlassSurface(tint: reality.decisionTint.opacity(0.22), cornerRadius: 38) {
|
||||||
|
VStack(alignment: .leading, spacing: 14) {
|
||||||
|
Label("What I am showing", systemImage: "eye.fill")
|
||||||
|
.font(.title2.weight(.black))
|
||||||
|
Text(reality.decisionTitle)
|
||||||
|
.font(.system(size: 56, weight: .black, design: .rounded))
|
||||||
|
.foregroundStyle(reality.decisionTint)
|
||||||
|
Text(reality.decisionExplanation)
|
||||||
|
.font(.title3.weight(.semibold))
|
||||||
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
|
Text(reality.currentInstruction)
|
||||||
|
.font(.callout)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
}
|
||||||
|
.padding(24)
|
||||||
|
}
|
||||||
|
|
||||||
|
LiquidGlassSurface(tint: .cyan.opacity(0.16), cornerRadius: 38) {
|
||||||
|
VStack(alignment: .leading, spacing: 14) {
|
||||||
|
Label("Snapshot artifact", systemImage: "doc.text.magnifyingglass")
|
||||||
|
.font(.title2.weight(.black))
|
||||||
|
Text("The SwiftUI app writes exactly this semantic view state into the repo.")
|
||||||
|
.font(.callout)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
Button {
|
||||||
|
store.writeRealitySnapshot(section: section)
|
||||||
|
} label: {
|
||||||
|
Label("Write Snapshot Now", systemImage: "square.and.arrow.down")
|
||||||
|
}
|
||||||
|
.buttonStyle(.glassProminent)
|
||||||
|
.tint(.cyan)
|
||||||
|
Text("data/app_visual_state.md\n data/app_visual_state.json")
|
||||||
|
.font(.body.monospaced())
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
.textSelection(.enabled)
|
||||||
|
}
|
||||||
|
.padding(24)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LiquidGlassSurface(tint: .white.opacity(0.08), cornerRadius: 34) {
|
||||||
|
VStack(alignment: .leading, spacing: 14) {
|
||||||
|
Label("Current visible facts", systemImage: "list.bullet.rectangle")
|
||||||
|
.font(.title2.weight(.black))
|
||||||
|
ValueGrid(rows: reality.factGridRows)
|
||||||
|
}
|
||||||
|
.padding(22)
|
||||||
|
}
|
||||||
|
|
||||||
|
LiquidGlassSurface(tint: .green.opacity(0.12), cornerRadius: 34) {
|
||||||
|
VStack(alignment: .leading, spacing: 14) {
|
||||||
|
Label("Buttons I believe are visible", systemImage: "cursorarrow.click.2")
|
||||||
|
.font(.title2.weight(.black))
|
||||||
|
ForEach(reality.visibleButtons, id: \.self) { button in
|
||||||
|
Text(button)
|
||||||
|
.font(.body.monospaced())
|
||||||
|
.textSelection(.enabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(22)
|
||||||
|
}
|
||||||
|
|
||||||
|
LiquidGlassSurface(tint: .orange.opacity(0.12), cornerRadius: 34) {
|
||||||
|
VStack(alignment: .leading, spacing: 14) {
|
||||||
|
Label("Operator truth", systemImage: "exclamationmark.shield")
|
||||||
|
.font(.title2.weight(.black))
|
||||||
|
ForEach(reality.operatorTruths, id: \.self) { truth in
|
||||||
|
Text(truth)
|
||||||
|
.font(.callout)
|
||||||
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(22)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onAppear {
|
||||||
|
store.writeRealitySnapshot(section: section)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct SectionHeader: View {
|
struct SectionHeader: View {
|
||||||
let title: String
|
let title: String
|
||||||
let subtitle: String
|
let subtitle: String
|
||||||
|
|
@ -1323,6 +1511,305 @@ enum ControlOwner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct RealityRow: Codable, Hashable {
|
||||||
|
let label: String
|
||||||
|
let value: String
|
||||||
|
let unit: String
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RenderedReality: Codable {
|
||||||
|
let snapshotGeneratedAt: String
|
||||||
|
let source: String
|
||||||
|
let visibleSection: String
|
||||||
|
let visibleSectionSubtitle: String
|
||||||
|
let decisionTitle: String
|
||||||
|
let decisionExplanation: String
|
||||||
|
let controlTitle: String
|
||||||
|
let controlDetail: String
|
||||||
|
let nextTitle: String
|
||||||
|
let nextDetail: String
|
||||||
|
let currentInstruction: String
|
||||||
|
let engineRunning: Bool
|
||||||
|
let engineDetail: String
|
||||||
|
let operation: String
|
||||||
|
let errorMessage: String
|
||||||
|
let latestStrategyAction: String
|
||||||
|
let latestReport: String
|
||||||
|
let activeWatch: String
|
||||||
|
let completedWatch: String
|
||||||
|
let activeManualExposure: String
|
||||||
|
let braiinsFreshness: String
|
||||||
|
let latestOceanSample: String
|
||||||
|
let latestBraiinsSample: String
|
||||||
|
let instrumentRows: [RealityRow]
|
||||||
|
let visibleButtons: [String]
|
||||||
|
let operatorTruths: [String]
|
||||||
|
|
||||||
|
var factRows: [RealityRow] {
|
||||||
|
[
|
||||||
|
RealityRow(label: "visible section", value: visibleSection, unit: "screen"),
|
||||||
|
RealityRow(label: "decision", value: decisionTitle, unit: "giant word"),
|
||||||
|
RealityRow(label: "control", value: controlTitle, unit: "owner"),
|
||||||
|
RealityRow(label: "next", value: nextTitle, unit: "action"),
|
||||||
|
RealityRow(label: "engine", value: engineRunning ? "running" : "stopped", unit: "state"),
|
||||||
|
RealityRow(label: "strategy", value: latestStrategyAction, unit: "proposal"),
|
||||||
|
RealityRow(label: "braiins", value: braiinsFreshness, unit: "freshness"),
|
||||||
|
RealityRow(label: "manual exposure", value: activeManualExposure, unit: "blocker"),
|
||||||
|
] + instrumentRows
|
||||||
|
}
|
||||||
|
|
||||||
|
var factGridRows: [(String, String, String)] {
|
||||||
|
factRows.map { ($0.label, $0.value, $0.unit) }
|
||||||
|
}
|
||||||
|
|
||||||
|
var decisionTint: Color {
|
||||||
|
switch decisionTitle {
|
||||||
|
case "ENGINE LIVE", "REFRESH", "WATCH", "REVIEW":
|
||||||
|
.green
|
||||||
|
case "WORKING", "HOLD", "WAIT", "COOLDOWN":
|
||||||
|
.orange
|
||||||
|
default:
|
||||||
|
.secondary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func make(
|
||||||
|
section: AppSection,
|
||||||
|
appState: AppStatePayload?,
|
||||||
|
isWorking: Bool,
|
||||||
|
operation: String?,
|
||||||
|
errorMessage: String?
|
||||||
|
) -> RenderedReality {
|
||||||
|
let decision = Decision.from(appState, isWorking: isWorking)
|
||||||
|
let control = ControlOwner.from(appState, isWorking: isWorking)
|
||||||
|
let next = nextAction(appState)
|
||||||
|
let latest = appState?.latest
|
||||||
|
let operatorState = appState?.operatorState
|
||||||
|
let engineStatus = appState?.engineStatus
|
||||||
|
let activePositions = operatorState?.activeManualPositions ?? []
|
||||||
|
let completedWatch = operatorState?.completedWatch
|
||||||
|
let buttons = visibleButtons(section: section, appState: appState, isWorking: isWorking)
|
||||||
|
let truths = operatorTruths(
|
||||||
|
decision: decision,
|
||||||
|
appState: appState,
|
||||||
|
activePositions: activePositions,
|
||||||
|
completedWatch: completedWatch
|
||||||
|
)
|
||||||
|
|
||||||
|
return RenderedReality(
|
||||||
|
snapshotGeneratedAt: ISO8601DateFormatter().string(from: Date()),
|
||||||
|
source: "SwiftUI rendered semantic state; this is not a screenshot or generic documentation.",
|
||||||
|
visibleSection: section.title,
|
||||||
|
visibleSectionSubtitle: section.subtitle,
|
||||||
|
decisionTitle: decision.title,
|
||||||
|
decisionExplanation: decision.explanation,
|
||||||
|
controlTitle: control.title,
|
||||||
|
controlDetail: control.detail,
|
||||||
|
nextTitle: next.title,
|
||||||
|
nextDetail: next.detail,
|
||||||
|
currentInstruction: next.instruction,
|
||||||
|
engineRunning: engineStatus?.running == true,
|
||||||
|
engineDetail: engineStatus?.detail ?? "engine state not loaded",
|
||||||
|
operation: operation ?? "none",
|
||||||
|
errorMessage: errorMessage ?? "none",
|
||||||
|
latestStrategyAction: operatorState?.action ?? "none",
|
||||||
|
latestReport: operatorState?.latestReport ?? "none",
|
||||||
|
activeWatch: operatorState?.activeWatch ?? "none",
|
||||||
|
completedWatch: completedWatch.map { "\($0.reportPath), remaining \($0.remainingMinutes)m, earliest \($0.earliestActionLocal)" } ?? "none",
|
||||||
|
activeManualExposure: activePositions.isEmpty ? "none" : activePositions.joined(separator: "; "),
|
||||||
|
braiinsFreshness: freshnessText(operatorState),
|
||||||
|
latestOceanSample: operatorState?.latestOceanTimestamp ?? "none",
|
||||||
|
latestBraiinsSample: operatorState?.latestMarketTimestamp ?? "none",
|
||||||
|
instrumentRows: [
|
||||||
|
RealityRow(label: "braiins price", value: marketValue(latest, "fillable_price_btc_per_eh_day", fallback: marketValue(latest, "best_ask_btc_per_eh_day")), unit: "BTC/EH/day"),
|
||||||
|
RealityRow(label: "ocean hashrate", value: oceanValue(latest, "pool_hashrate_eh_s"), unit: "EH/s"),
|
||||||
|
RealityRow(label: "pool window", value: oceanValue(latest, "avg_block_time_hours"), unit: "h/block"),
|
||||||
|
RealityRow(label: "expected net", value: sats(proposalValue(latest, "expected_net_btc")), unit: "model"),
|
||||||
|
],
|
||||||
|
visibleButtons: buttons,
|
||||||
|
operatorTruths: truths
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func nextAction(_ appState: AppStatePayload?) -> (title: String, detail: String, instruction: String) {
|
||||||
|
guard let state = appState else {
|
||||||
|
return ("Load state", "Reading durable SQLite state.", "Wait for the app-state load to finish.")
|
||||||
|
}
|
||||||
|
if state.engineStatus.running {
|
||||||
|
return (
|
||||||
|
"Engine owns it",
|
||||||
|
"No babysitting. The background engine waits, samples, watches, and writes evidence.",
|
||||||
|
"Do nothing unless you intentionally want to stop the engine or record manual exposure."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if state.operatorState.activeWatch != nil {
|
||||||
|
return (
|
||||||
|
"Wait for watch",
|
||||||
|
"A passive watch is already running.",
|
||||||
|
"Do not start another watch. Wait for the current run report."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if let watch = state.operatorState.completedWatch {
|
||||||
|
return (
|
||||||
|
"Wait \(watch.remainingMinutes)m",
|
||||||
|
"Earliest useful action: \(watch.earliestActionLocal).",
|
||||||
|
"Cooldown is active. Do not repeat the same experiment yet."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if !state.operatorState.activeManualPositions.isEmpty {
|
||||||
|
return (
|
||||||
|
"Hold exposure",
|
||||||
|
"A manually recorded Braiins position blocks new experiments.",
|
||||||
|
"Supervise the real position. Close it only when it is truly finished."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
let step = state.automationPlan.steps.first ?? "No passive action is useful right now."
|
||||||
|
return (state.automationPlan.title, step, step)
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func visibleButtons(section: AppSection, appState: AppStatePayload?, isWorking: Bool) -> [String] {
|
||||||
|
var buttons = ["Toolbar: Refresh"]
|
||||||
|
if appState?.engineStatus.running == true {
|
||||||
|
buttons.append("Toolbar: Stop Engine")
|
||||||
|
} else {
|
||||||
|
buttons.append("Toolbar: Start Engine")
|
||||||
|
}
|
||||||
|
switch section {
|
||||||
|
case .deck:
|
||||||
|
buttons.append(contentsOf: ["Flight Deck: Start Forever Engine", "Flight Deck: Stop", "Flight Deck: One Sample"])
|
||||||
|
case .exposure:
|
||||||
|
buttons.append(contentsOf: ["Exposure: Record Exposure", "Exposure: Close Exposure"])
|
||||||
|
case .vault:
|
||||||
|
buttons.append(contentsOf: ["Evidence: Cockpit", "Evidence: Report", "Evidence: Ledger"])
|
||||||
|
case .mirror:
|
||||||
|
buttons.append("Reality Mirror: Write Snapshot Now")
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if isWorking {
|
||||||
|
buttons.append("State: some buttons are disabled because an operation is running")
|
||||||
|
}
|
||||||
|
return buttons
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func operatorTruths(
|
||||||
|
decision: Decision,
|
||||||
|
appState: AppStatePayload?,
|
||||||
|
activePositions: [String],
|
||||||
|
completedWatch: CompletedWatchPayload?
|
||||||
|
) -> [String] {
|
||||||
|
if appState == nil {
|
||||||
|
return ["The app has not loaded structured backend state yet."]
|
||||||
|
}
|
||||||
|
if !activePositions.isEmpty {
|
||||||
|
return [
|
||||||
|
"Real manual exposure is recorded.",
|
||||||
|
"New watch experiments should remain blocked until the exposure is closed."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if appState?.engineStatus.running == true {
|
||||||
|
return [
|
||||||
|
"The forever engine owns passive research.",
|
||||||
|
"The safest operator workload is zero unless you need to record real exposure."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if let completedWatch {
|
||||||
|
return [
|
||||||
|
"A watch already produced evidence.",
|
||||||
|
"Earliest useful next action is \(completedWatch.earliestActionLocal)."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
switch decision {
|
||||||
|
case .watch:
|
||||||
|
return ["A passive watch or the forever engine is the current research action; no BTC is spent by the app."]
|
||||||
|
case .review:
|
||||||
|
return ["Manual review is required before any Braiins action; the app still cannot spend BTC."]
|
||||||
|
case .observe:
|
||||||
|
return ["No useful action window is visible; doing nothing is the intended action."]
|
||||||
|
default:
|
||||||
|
return [decision.explanation]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func freshnessText(_ state: OperatorStatePayload?) -> String {
|
||||||
|
guard let minutes = state?.freshnessMinutes else { return "unknown" }
|
||||||
|
return minutes <= 30 ? "fresh (\(minutes)m)" : "stale (\(minutes)m)"
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func marketValue(_ latest: LatestPayload?, _ key: String, fallback: String = "n/a") -> String {
|
||||||
|
latest?.market?[key]?.description ?? fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func oceanValue(_ latest: LatestPayload?, _ key: String) -> String {
|
||||||
|
latest?.ocean?[key]?.description ?? "n/a"
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func proposalValue(_ latest: LatestPayload?, _ key: String) -> String {
|
||||||
|
latest?.proposal?[key]?.description ?? "n/a"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum RealitySnapshotWriter {
|
||||||
|
static func write(_ reality: RenderedReality) {
|
||||||
|
guard let repoRoot = RatchetProcess.repoRootURL() else { return }
|
||||||
|
let dataDir = repoRoot.appendingPathComponent("data", isDirectory: true)
|
||||||
|
do {
|
||||||
|
try FileManager.default.createDirectory(at: dataDir, withIntermediateDirectories: true)
|
||||||
|
let encoder = JSONEncoder()
|
||||||
|
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
|
||||||
|
let jsonData = try encoder.encode(reality)
|
||||||
|
try jsonData.write(to: dataDir.appendingPathComponent("app_visual_state.json"), options: .atomic)
|
||||||
|
try renderMarkdown(reality).write(
|
||||||
|
to: dataDir.appendingPathComponent("app_visual_state.md"),
|
||||||
|
atomically: true,
|
||||||
|
encoding: .utf8
|
||||||
|
)
|
||||||
|
} catch {
|
||||||
|
// This is diagnostic output only. UI operation must never fail because the mirror file cannot be written.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func renderMarkdown(_ reality: RenderedReality) -> String {
|
||||||
|
var lines = [
|
||||||
|
"# App Visual State",
|
||||||
|
"",
|
||||||
|
"This file is written by the SwiftUI app. It records the app's semantic rendered state, not generic documentation.",
|
||||||
|
"",
|
||||||
|
"- snapshot_generated_at: \(reality.snapshotGeneratedAt)",
|
||||||
|
"- visible_section: \(reality.visibleSection)",
|
||||||
|
"- decision: \(reality.decisionTitle)",
|
||||||
|
"- decision_explanation: \(reality.decisionExplanation)",
|
||||||
|
"- control: \(reality.controlTitle)",
|
||||||
|
"- control_detail: \(reality.controlDetail)",
|
||||||
|
"- next: \(reality.nextTitle)",
|
||||||
|
"- next_detail: \(reality.nextDetail)",
|
||||||
|
"- current_instruction: \(reality.currentInstruction)",
|
||||||
|
"- engine_running: \(reality.engineRunning ? "yes" : "no")",
|
||||||
|
"- engine_detail: \(reality.engineDetail)",
|
||||||
|
"- operation: \(reality.operation)",
|
||||||
|
"- error_message: \(reality.errorMessage)",
|
||||||
|
"- latest_strategy_action: \(reality.latestStrategyAction)",
|
||||||
|
"- braiins_freshness: \(reality.braiinsFreshness)",
|
||||||
|
"- latest_ocean_sample: \(reality.latestOceanSample)",
|
||||||
|
"- latest_braiins_sample: \(reality.latestBraiinsSample)",
|
||||||
|
"- latest_report: \(reality.latestReport)",
|
||||||
|
"- active_watch: \(reality.activeWatch)",
|
||||||
|
"- completed_watch: \(reality.completedWatch)",
|
||||||
|
"- active_manual_exposure: \(reality.activeManualExposure)",
|
||||||
|
"",
|
||||||
|
"## Instruments",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
lines.append(contentsOf: reality.instrumentRows.map { "- \($0.label): \($0.value) \($0.unit)" })
|
||||||
|
lines.append(contentsOf: ["", "## Visible Buttons", ""])
|
||||||
|
lines.append(contentsOf: reality.visibleButtons.map { "- \($0)" })
|
||||||
|
lines.append(contentsOf: ["", "## Operator Truths", ""])
|
||||||
|
lines.append(contentsOf: reality.operatorTruths.map { "- \($0)" })
|
||||||
|
lines.append("")
|
||||||
|
return lines.joined(separator: "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum ResearchPhase {
|
enum ResearchPhase {
|
||||||
case loading
|
case loading
|
||||||
case refresh
|
case refresh
|
||||||
|
|
@ -1561,6 +2048,10 @@ enum AppIconFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum RatchetProcess {
|
enum RatchetProcess {
|
||||||
|
static func repoRootURL() -> URL? {
|
||||||
|
findRepoRoot()
|
||||||
|
}
|
||||||
|
|
||||||
static func loadAppState() async -> AppStateLoadResult {
|
static func loadAppState() async -> AppStateLoadResult {
|
||||||
await Task.detached {
|
await Task.detached {
|
||||||
guard let repoRoot = findRepoRoot() else {
|
guard let repoRoot = findRepoRoot() else {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ Commands:
|
||||||
supervise Run the durable forever lifecycle supervisor.
|
supervise Run the durable forever lifecycle supervisor.
|
||||||
engine Start/stop/status for the background monitor engine.
|
engine Start/stop/status for the background monitor engine.
|
||||||
app Build and open the native macOS app.
|
app Build and open the native macOS app.
|
||||||
|
mirror Print the app's latest self-written visual-state snapshot.
|
||||||
position Record/list/close manually executed Braiins exposure.
|
position Record/list/close manually executed Braiins exposure.
|
||||||
report Print the latest stored report without fetching new data.
|
report Print the latest stored report without fetching new data.
|
||||||
app-state Print structured JSON for the native macOS app.
|
app-state Print structured JSON for the native macOS app.
|
||||||
|
|
@ -36,6 +37,7 @@ Examples:
|
||||||
./scripts/ratchet supervise
|
./scripts/ratchet supervise
|
||||||
./scripts/ratchet engine status
|
./scripts/ratchet engine status
|
||||||
./scripts/ratchet app
|
./scripts/ratchet app
|
||||||
|
./scripts/ratchet mirror
|
||||||
./scripts/ratchet position list
|
./scripts/ratchet position list
|
||||||
./scripts/ratchet report
|
./scripts/ratchet report
|
||||||
./scripts/ratchet experiments
|
./scripts/ratchet experiments
|
||||||
|
|
@ -142,6 +144,17 @@ cmd_app() {
|
||||||
open "$app_path"
|
open "$app_path"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd_mirror() {
|
||||||
|
local path="$ROOT_DIR/data/app_visual_state.md"
|
||||||
|
if [[ ! -f "$path" ]]; then
|
||||||
|
echo "No app visual-state snapshot exists yet."
|
||||||
|
echo "Open the native app with: ./scripts/ratchet app"
|
||||||
|
echo "Then refresh or open the Reality Mirror tab."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
cat "$path"
|
||||||
|
}
|
||||||
|
|
||||||
cmd_position() {
|
cmd_position() {
|
||||||
run_python -m braiins_ratchet.cli position "$@"
|
run_python -m braiins_ratchet.cli position "$@"
|
||||||
}
|
}
|
||||||
|
|
@ -194,6 +207,7 @@ main() {
|
||||||
supervise|daemon) cmd_supervise "$@" ;;
|
supervise|daemon) cmd_supervise "$@" ;;
|
||||||
engine) cmd_engine "$@" ;;
|
engine) cmd_engine "$@" ;;
|
||||||
app|mac-app) cmd_app "$@" ;;
|
app|mac-app) cmd_app "$@" ;;
|
||||||
|
mirror|reality) cmd_mirror "$@" ;;
|
||||||
position|positions) cmd_position "$@" ;;
|
position|positions) cmd_position "$@" ;;
|
||||||
report) cmd_report "$@" ;;
|
report) cmd_report "$@" ;;
|
||||||
app-state) cmd_app_state "$@" ;;
|
app-state) cmd_app_state "$@" ;;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,9 @@ class DocumentationContractTests(unittest.TestCase):
|
||||||
self.assertIn("Immediate", text)
|
self.assertIn("Immediate", text)
|
||||||
self.assertIn("Midterm", text)
|
self.assertIn("Midterm", text)
|
||||||
self.assertIn("Longterm", text)
|
self.assertIn("Longterm", text)
|
||||||
|
self.assertIn("Reality Mirror", text)
|
||||||
|
self.assertIn("Backstage Evidence Deck", text)
|
||||||
|
self.assertIn("data/app_visual_state.md", text)
|
||||||
self.assertIn("Potential Findings", text)
|
self.assertIn("Potential Findings", text)
|
||||||
self.assertIn("manual_canary", text)
|
self.assertIn("manual_canary", text)
|
||||||
self.assertIn("manual_bid", text)
|
self.assertIn("manual_bid", text)
|
||||||
|
|
@ -37,6 +40,8 @@ class DocumentationContractTests(unittest.TestCase):
|
||||||
self.assertIn("SQLite durable state", text)
|
self.assertIn("SQLite durable state", text)
|
||||||
self.assertIn("Switching To Another macOS Host", text)
|
self.assertIn("Switching To Another macOS Host", text)
|
||||||
self.assertIn("State Recovery", text)
|
self.assertIn("State Recovery", text)
|
||||||
|
self.assertIn("visual self-reflection layer", text)
|
||||||
|
self.assertIn("data/app_visual_state.json", text)
|
||||||
self.assertIn("data/ratchet.sqlite*", text)
|
self.assertIn("data/ratchet.sqlite*", text)
|
||||||
self.assertIn("reports/EXPERIMENT_LOG.md", text)
|
self.assertIn("reports/EXPERIMENT_LOG.md", text)
|
||||||
self.assertIn("git clone -b master", text)
|
self.assertIn("git clone -b master", text)
|
||||||
|
|
@ -51,10 +56,13 @@ class DocumentationContractTests(unittest.TestCase):
|
||||||
self.assertIn("docs/OPERATOR_GUIDE.md", readme)
|
self.assertIn("docs/OPERATOR_GUIDE.md", readme)
|
||||||
self.assertIn("./scripts/ratchet guide", readme)
|
self.assertIn("./scripts/ratchet guide", readme)
|
||||||
self.assertIn("./scripts/ratchet operator-guide", readme)
|
self.assertIn("./scripts/ratchet operator-guide", readme)
|
||||||
|
self.assertIn("./scripts/ratchet mirror", readme)
|
||||||
self.assertIn("./scripts/ratchet guide", start_here)
|
self.assertIn("./scripts/ratchet guide", start_here)
|
||||||
self.assertIn("./scripts/ratchet operator-guide", start_here)
|
self.assertIn("./scripts/ratchet operator-guide", start_here)
|
||||||
|
self.assertIn("./scripts/ratchet mirror", start_here)
|
||||||
self.assertIn("guide|user-guide|explain", wrapper)
|
self.assertIn("guide|user-guide|explain", wrapper)
|
||||||
self.assertIn("operator-guide|operator", wrapper)
|
self.assertIn("operator-guide|operator", wrapper)
|
||||||
|
self.assertIn("mirror|reality", wrapper)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ class MacAppPackagingTest(unittest.TestCase):
|
||||||
self.assertIn("cmd_app", text)
|
self.assertIn("cmd_app", text)
|
||||||
self.assertIn("app-state", text)
|
self.assertIn("app-state", text)
|
||||||
self.assertIn("engine", text)
|
self.assertIn("engine", text)
|
||||||
|
self.assertIn("mirror|reality", text)
|
||||||
|
self.assertIn("app_visual_state.md", text)
|
||||||
self.assertIn("pkill -x BraiinsRatchetMac", text)
|
self.assertIn("pkill -x BraiinsRatchetMac", text)
|
||||||
self.assertNotIn("swift run BraiinsRatchetMac", text)
|
self.assertNotIn("swift run BraiinsRatchetMac", text)
|
||||||
|
|
||||||
|
|
@ -87,9 +89,14 @@ class MacAppPackagingTest(unittest.TestCase):
|
||||||
self.assertIn("RatchetMapView", text)
|
self.assertIn("RatchetMapView", text)
|
||||||
self.assertIn("BidLabView", text)
|
self.assertIn("BidLabView", text)
|
||||||
self.assertIn("EvidenceVaultView", text)
|
self.assertIn("EvidenceVaultView", text)
|
||||||
|
self.assertIn("RealityMirrorView", text)
|
||||||
|
self.assertIn("RealityHUD", text)
|
||||||
|
self.assertIn("RenderedReality", text)
|
||||||
|
self.assertIn("RealitySnapshotWriter", text)
|
||||||
self.assertIn("AppStatePayload", text)
|
self.assertIn("AppStatePayload", text)
|
||||||
self.assertIn("EngineStatusPayload", text)
|
self.assertIn("EngineStatusPayload", text)
|
||||||
self.assertIn("loadAppState", text)
|
self.assertIn("loadAppState", text)
|
||||||
|
self.assertIn("repoRootURL", text)
|
||||||
self.assertIn("Start Forever Engine", text)
|
self.assertIn("Start Forever Engine", text)
|
||||||
self.assertIn("glassEffect", text)
|
self.assertIn("glassEffect", text)
|
||||||
self.assertIn("GlassEffectContainer", text)
|
self.assertIn("GlassEffectContainer", text)
|
||||||
|
|
@ -97,6 +104,10 @@ class MacAppPackagingTest(unittest.TestCase):
|
||||||
self.assertIn("backgroundExtensionEffect", text)
|
self.assertIn("backgroundExtensionEffect", text)
|
||||||
self.assertIn("searchable", text)
|
self.assertIn("searchable", text)
|
||||||
self.assertIn("Flight Deck", text)
|
self.assertIn("Flight Deck", text)
|
||||||
|
self.assertIn("Reality Mirror", text)
|
||||||
|
self.assertIn("BED: Backstage Evidence Deck", text)
|
||||||
|
self.assertIn("app_visual_state.md", text)
|
||||||
|
self.assertIn("app_visual_state.json", text)
|
||||||
self.assertIn("Bid Lab", text)
|
self.assertIn("Bid Lab", text)
|
||||||
self.assertNotIn("MissionControlView", text)
|
self.assertNotIn("MissionControlView", text)
|
||||||
self.assertNotIn("MiningStackView", text)
|
self.assertNotIn("MiningStackView", text)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue