@@ -81,6 +81,9 @@ final class ReleaseReadinessScriptTests: XCTestCase {
8181 XCTAssertTrue ( script. contains ( " release_proof_is_known_gate \" $gate \" " ) )
8282 XCTAssertTrue ( script. contains ( " --artifact <path> " ) )
8383 XCTAssertTrue ( script. contains ( " Missing required --gate, --output, --command, or --artifact. " ) )
84+ XCTAssertTrue ( script. contains ( " release_proof_required_command_token_for_gate " ) )
85+ XCTAssertTrue ( script. contains ( " Proof command must include '$required_command_token' " ) )
86+ XCTAssertTrue ( script. contains ( " Proof date must be UTC ISO-8601 " ) )
8487 XCTAssertTrue ( script. contains ( " gate: %s " ) )
8588 XCTAssertTrue ( script. contains ( " status: passed " ) )
8689 XCTAssertTrue ( script. contains ( " date: %s " ) )
@@ -175,6 +178,47 @@ final class ReleaseReadinessScriptTests: XCTestCase {
175178 XCTAssertTrue ( invalidDateResult. output. contains ( " date must be UTC ISO-8601 " ) )
176179 }
177180
181+ func testReleaseProofWriterRejectsInvalidCommandTokenAndDate( ) throws {
182+ let temporaryDirectory = URL ( fileURLWithPath: NSTemporaryDirectory ( ) )
183+ . appendingPathComponent ( " LiveKitNativeReleaseProofWriter- \( UUID ( ) . uuidString) " )
184+ try FileManager . default. createDirectory ( at: temporaryDirectory, withIntermediateDirectories: true )
185+ defer { try ? FileManager . default. removeItem ( at: temporaryDirectory) }
186+
187+ let artifact = temporaryDirectory. appendingPathComponent ( " simulcast.log " )
188+ try " ok \n " . write ( to: artifact, atomically: true , encoding: . utf8)
189+
190+ let validOutput = temporaryDirectory. appendingPathComponent ( " simulcast.proof " )
191+ let validResult = try runReleaseProofWriter (
192+ gate: " simulcast " ,
193+ output: validOutput,
194+ command: " LIVEKIT_NATIVE_RUN_INTEGRATION=1 LIVEKIT_NATIVE_RUN_SIMULCAST=1 swift test " ,
195+ artifact: artifact,
196+ date: " 2026-05-19T00:00:00Z "
197+ )
198+ XCTAssertEqual ( validResult. status, 0 , validResult. output)
199+ XCTAssertTrue ( FileManager . default. fileExists ( atPath: validOutput. path) )
200+
201+ let missingTokenResult = try runReleaseProofWriter (
202+ gate: " simulcast " ,
203+ output: temporaryDirectory. appendingPathComponent ( " simulcast-missing-token.proof " ) ,
204+ command: " LIVEKIT_NATIVE_RUN_INTEGRATION=1 swift test " ,
205+ artifact: artifact,
206+ date: " 2026-05-19T00:00:00Z "
207+ )
208+ XCTAssertNotEqual ( missingTokenResult. status, 0 )
209+ XCTAssertTrue ( missingTokenResult. output. contains ( " Proof command must include 'LIVEKIT_NATIVE_RUN_SIMULCAST=1' " ) )
210+
211+ let invalidDateResult = try runReleaseProofWriter (
212+ gate: " simulcast " ,
213+ output: temporaryDirectory. appendingPathComponent ( " simulcast-invalid-date.proof " ) ,
214+ command: " LIVEKIT_NATIVE_RUN_INTEGRATION=1 LIVEKIT_NATIVE_RUN_SIMULCAST=1 swift test " ,
215+ artifact: artifact,
216+ date: " 2026-05-19 "
217+ )
218+ XCTAssertNotEqual ( invalidDateResult. status, 0 )
219+ XCTAssertTrue ( invalidDateResult. output. contains ( " Proof date must be UTC ISO-8601 " ) )
220+ }
221+
178222 func testReleaseProofDocsMatchRequiredProofSpecs( ) throws {
179223 let gates = try String ( contentsOf: repositoryRoot. appendingPathComponent ( " scripts/release_proof_gates.sh " ) )
180224 let docs = try String ( contentsOf: repositoryRoot. appendingPathComponent ( " docs/RELEASE_PROOFS.md " ) )
@@ -355,6 +399,41 @@ final class ReleaseReadinessScriptTests: XCTestCase {
355399 return ( process. terminationStatus, String ( data: data, encoding: . utf8) ?? " " )
356400 }
357401
402+ private func runReleaseProofWriter(
403+ gate: String ,
404+ output: URL ,
405+ command: String ,
406+ artifact: URL ,
407+ date: String
408+ ) throws -> ( status: Int32 , output: String ) {
409+ let process = Process ( )
410+ let capturedOutput = Pipe ( )
411+ process. executableURL = URL ( fileURLWithPath: " /bin/bash " )
412+ process. currentDirectoryURL = repositoryRoot
413+ process. arguments = [
414+ repositoryRoot. appendingPathComponent ( " scripts/write_release_proof.sh " ) . path,
415+ " --gate " ,
416+ gate,
417+ " --output " ,
418+ output. path,
419+ " --command " ,
420+ command,
421+ " --artifact " ,
422+ artifact. path,
423+ " --runner " ,
424+ " unit-test " ,
425+ " --date " ,
426+ date,
427+ ]
428+ process. standardOutput = capturedOutput
429+ process. standardError = capturedOutput
430+ try process. run ( )
431+ process. waitUntilExit ( )
432+
433+ let data = capturedOutput. fileHandleForReading. readDataToEndOfFile ( )
434+ return ( process. terminationStatus, String ( data: data, encoding: . utf8) ?? " " )
435+ }
436+
358437 private func strictProductionFlags( in script: String ) -> [ String ] {
359438 guard let start = script. range ( of: " for required_strict_flag in \\ " ) else {
360439 XCTFail ( " Expected strict flag loop in check_release_readiness.sh. " )
0 commit comments