oficina / calendar Public

Verify native event forms and record release review

Co-Authored-By: Codex <codex~paul@keymail.dev>
codex agent, operated by paul@keymail.dev 8c908137b2073b37adc341f1bcc3f04069538ce8 parent d3fedf1
5 files changed, +67 −0
  • internal/calendar/native_test.go +10 −0
  • native/README.md +8 −0
  • native/REVIEW.md +11 −0
  • native/ios/UITests/NativeUITests.swift +20 −0
  • native/ios/project.yml +18 −0
diff --git a/internal/calendar/native_test.go b/internal/calendar/native_test.go
index d116f35..0c847d6 100644
--- a/internal/calendar/native_test.go
+++ b/internal/calendar/native_test.go
@@ -100,6 +100,16 @@ func TestNativeCalendarRoundTrip(t *testing.T) {
t.Fatal(err)
}
defer os.Remove(path)
+
+ if os.Getenv("NATIVE_REVIEW_UI_TESTS") != "" {
+ command := exec.CommandContext(t.Context(), "xcodebuild", "-project", "native/ios/CalendarPhone.xcodeproj", "-scheme", "CalendarReviewPhone", "-destination", "platform=iOS Simulator,id="+simulator, "-derivedDataPath", "native/build/ios", "CODE_SIGNING_ALLOWED=NO", "test")
+ command.Dir = "../.."
+ output, err := command.CombinedOutput()
+ _ = os.WriteFile(filepath.Join(os.TempDir(), "calendar-native-ui-tests.log"), output, 0600)
+ if err != nil {
+ t.Fatal("Native UI tests failed; see temporary xcodebuild log", err)
+ }
+ }
run("launch", simulator, bundle)
time.Sleep(3 * time.Second)
run("io", simulator, "screenshot", os.Getenv("NATIVE_REVIEW_OUTPUT"))
diff --git a/native/README.md b/native/README.md
index 6468401..7954173 100644
--- a/native/README.md
+++ b/native/README.md
@@ -31,3 +31,11 @@ maximum 62-day half-open range, and POST `/api/native/events[/{id}]`. Existing
person, calendar-grant and event-store checks remain authoritative. Recurrence
expansion stays on the server. All-day ends are exclusive dates. The UI uses the
person's saved week start and time zone, not the device's implicit formatting zone.
+
+For XCTest interaction checks against the isolated authenticated fixture, set
+`NATIVE_REVIEW_SIMULATOR=<UDID> NATIVE_REVIEW_UI_TESTS=1` with a writable
+`NATIVE_REVIEW_OUTPUT` PNG path when running the native Go fixture test. First
+build/install the separate ReviewPhone target. The UI tests create and inspect
+fixture events and never connect to a real account. Xcode result bundles
+are under `native/build/ios/Logs/Test`. Review credentials enter only the isolated
+review app's Documents directory and are removed when the fixture exits.
diff --git a/native/REVIEW.md b/native/REVIEW.md
index ab3772f..75df1ec 100644
--- a/native/REVIEW.md
+++ b/native/REVIEW.md
@@ -25,3 +25,14 @@ carries status and labels it explicitly; regression tests pin both states.
A confirmed event with a failed reminder now returns its saved id and a warning,
so the native editor closes successfully instead of inviting a duplicate retry.
A database-trigger failure test verifies that persisted event and warning.
+
+Final merge `d3fedf1` reviewed against both parents (58863aa and 9c44bc1) by
+`/root/canary_release_review`, dispatched as `gpt-6-astra` with high reasoning.
+Runtime model identity was not independently verified. Code and deployed canary
+review approved, with no remaining findings. Direct `/api/version` and the router
+reported the exact reviewed version. Native pending exchanges returned 202 without
+credentials; incorrect proofs returned 404, cross-origin requests 403, anonymous
+approval was refused, and failed approval left the request pending. No email or
+user-data mutation was performed. Existing credits access and branding remained
+intact. The final Go CI passed, and XCTest exercised native form and navigation
+against an isolated authenticated fixture.
diff --git a/native/ios/UITests/NativeUITests.swift b/native/ios/UITests/NativeUITests.swift
new file mode 100644
index 0000000..8c13f6a
--- /dev/null
+++ b/native/ios/UITests/NativeUITests.swift
@@ -0,0 +1,20 @@
+import XCTest
+@MainActor final class NativeUITests: XCTestCase {
+ func testNativeFormAndNavigation() {
+ let app=XCUIApplication();app.launch()
+ XCTAssertTrue(app.buttons["New event"].waitForExistence(timeout: 10))
+
+ app.buttons["New event"].tap()
+ let title=app.textFields["eventTitle"]
+ XCTAssertTrue(title.waitForExistence(timeout: 5)); title.tap(); title.typeText("Native UI event")
+ app.buttons["Save"].tap()
+ XCTAssertTrue(app.staticTexts["Native UI event"].firstMatch.waitForExistence(timeout: 10))
+ app.staticTexts["Native UI event"].firstMatch.tap()
+ XCTAssertTrue(app.buttons["Edit event"].waitForExistence(timeout: 5))
+ app.buttons["Edit event"].tap()
+ XCTAssertTrue(app.textFields["eventTitle"].waitForExistence(timeout: 5))
+ app.buttons["Cancel"].tap()
+
+ let capture=XCTAttachment(screenshot: app.screenshot());capture.lifetime = .keepAlways;add(capture)
+ }
+}
diff --git a/native/ios/project.yml b/native/ios/project.yml
index 35b76cd..f052032 100644
--- a/native/ios/project.yml
+++ b/native/ios/project.yml
@@ -54,3 +54,21 @@ targets:
TARGETED_DEVICE_FAMILY: '1,2'
GENERATE_INFOPLIST_FILE: YES
INFOPLIST_KEY_UILaunchScreen_Generation: YES
+
+ CalendarPhoneUITests:
+ type: bundle.ui-testing
+ platform: iOS
+ sources: [UITests]
+ dependencies:
+ - target: CalendarReviewPhone
+ settings:
+ base:
+ GENERATE_INFOPLIST_FILE: YES
+ TEST_TARGET_NAME: CalendarReviewPhone
+schemes:
+ CalendarReviewPhone:
+ build:
+ targets:
+ CalendarReviewPhone: all
+ test:
+ targets: [CalendarPhoneUITests]