The goal of this document is to ensure high-quality, reproducible, and verifiable contributions in a fully autonomous loop for the App Check repository.
Before starting any work, the agent must require or acquire:
- Feature Specification: A detailed description of the feature, bug, or task.
- Project Configuration: Access to necessary credentials or configurations if applicable.
- External Scripts: Access to the
firebase-ios-sdkscripts. If not using the cloned scripts via./setup-scripts.sh, ensure they are available in a local clone offirebase-ios-sdk(commonly at<path_to_firebase_ios_sdk>/scriptsbut path may vary). If the path is not found, ask the human for it.
A successful task completion MUST produce:
- Code Changes: The implemented feature or fix and corresponding tests.
- Unit & Integration Tests: Demonstrating success and handling edge cases.
- Implementation Plan (For complex tasks only): A scannable proposal before starting work.
- Walkthrough Artifact: A summary containing verification results and reproduction snippets.
When reporting back to the user, prioritize scannability and clarity:
- Use Categorized Bullet Points: Group findings and results into clear categories (e.g., "Build & Test Results", "Code Changes").
- Use Indicators: Prefix status updates with checkmarks (✅) or caution
symbols (
⚠️ ) for immediate visual parsing. - Be Concise: Avoid conversational filler. Get straight to the results and next steps.
- Final Report: Conclude the task with a concise summary of work and a recommended conventional commit message.
- Prerequisite: Verify that external scripts are accessible or that
./setup-scripts.shhas been run to link them. If you cannot find them, ask the human for the path to thefirebase-ios-sdkrepository. - Action: Assess the complexity of the task.
- Simple Task: Proceed directly to Step 1: TDD.
- Complex Task: Create a highly scannable Implementation Plan and get human approval.
- Plan Requirements (Highly Scannable):
- Keep it brief and hit key points.
- Use bullet points for readability.
- Focus on what changes and why, avoiding detailed how.
- Highlight any open questions or design decisions requiring human input.
- Constraint: You MUST write tests before writing implementation code.
- Action:
- Create or identify the correct test target in
Package.swift. Keep Swift and Obj-C test targets separate. - Write a failing unit or integration test asserting the new behavior.
- Verify it fails by running the appropriate test command (e.g.,
swift test --filter <TargetName>).
- Create or identify the correct test target in
- Implement the feature or fix.
- Follow project conventions and guidelines if available.
- Action: Run tests using the cloned scripts or by referencing the external
ones (e.g., in
<path_to_firebase_ios_sdk>). - Iteration Workflow: To get into a faster iterative loop, use the external
scripts directly if possible. Set an environment variable like
FIREBASE_IOS_SDK_PATHif your path differs from the default<path_to_firebase_ios_sdk>.- To bypass the CI secret check in
check_secrets.shwhen running external scripts in a trusted environment, exportFIREBASECI_IS_TRUSTED_ENV="true".
- To bypass the CI secret check in
- Commands:
- Primary (Fast Iteration): For SPM testing (which uses
xcodebuildunder the hood):${FIREBASE_IOS_SDK_PATH:-<path_to_firebase_ios_sdk>}/scripts/build.sh AppCheck <platform> spm(where<platform>isiOS,tvOS,macOS, orcatalyst). - For CocoaPods linting:
${FIREBASE_IOS_SDK_PATH:-<path_to_firebase_ios_sdk>}/scripts/pod_lib_lint.rb AppCheckCore.podspec --platforms=ios(or other platforms:tvos,macos --skip-tests,watchos). - Alternatively, run
./setup-scripts.shto clone scripts locally and usescripts/pod_lib_lint.rb. - For Catalyst testing:
${FIREBASE_IOS_SDK_PATH:-<path_to_firebase_ios_sdk>}/scripts/test_catalyst.sh AppCheckCore test.
- Primary (Fast Iteration): For SPM testing (which uses
- xcodebuild Iteration: For direct
xcodebuildinvocations, follow the order:build,build-for-testing, thentest. This allows for faster iteration.
- Requirement: Identify and report any new public APIs created.
- Method: Check for changes in public headers or symbols.
- Action: You MUST run
<path_to_firebase_ios_sdk>/scripts/style.shto maintain consistency. - Constraint: Since style changes are non-functional, you do NOT need to re-run tests after applying style fixes.
- Requirement: Wrap all documentation files (like
agents.md) to be 80 characters or less (excluding code blocks). Remove all trailing whitespace.
- Error Handling: Test edge cases and error paths.
- No Hardcoded Secrets: Ensure no secrets are committed.
- Code Reuse & Refactoring: Prioritize understanding existing structures to reuse or extend them with minor refactors rather than adding redundant code.
- Unit Tests: Passed all unit tests.
- Integration Tests: Passed all integration tests.
- Style Applied: Verified code style if applicable.
- Concurrency: Verified that the changes do not introduce potential race conditions or deadlocks.
- Memory Management: Ensured no retain cycles or memory leaks are introduced.
- Commit Often: Pause and commit work frequently.
- Scope: Optimize for smaller commits that represent a complete piece of work or a specific milestone within a larger task.
- Convention: Follow conventional commit practices (e.g.
feat:,fix:,refactor:).
When operating in a restricted or sandboxed environment (like the Jetski IDE), you may encounter the following blockers. Use these workarounds:
- Terminal Sandbox (SPM
sandbox-execerrors):swift buildmay fail if run inside a sandbox. Disable the terminal sandbox in the IDE settings (enableTerminalSandbox: false) or useswift build --disable-sandbox. - Missing
pythonCommand: Modern macOS lackspython(Python 2). If external scripts fail, create a local wrapper script that forwards topython3and add it to thePATH:mkdir -p tmp/bin && echo '#!/bin/sh\nexec python3 "$@"' > tmp/bin/python && chmod +x tmp/bin/python && export PATH="$PWD/tmp/bin:$PATH" - Ruby Version Conflicts: External scripts (like
pod_lib_lint.rb) may fail ifrbenvtries to use the external repo's.ruby-version. Force the local Ruby version by prefixing the command withRBENV_VERSION=2.7.5. - Quality Gates: Do not skip
style.shandpod_lib_lint.rb. They are critical for verification. - Fixture Loading in Tests: When running tests via
swift teston macOS,GACFixtureLoadermay fail to find JSON fixtures due to bundle resolution issues, causing tests to fail withnil URL argumentexceptions. This is often an environment-specific issue with SPM resource bundles on macOS.
When working on mixed-language targets (e.g., Swift tests for Objective-C core
code), you will encounter strict compiler bridging issues, particularly with
generic classes like FBLPromise. To avoid build loop failures:
- FBLPromise Instantiation:
FBLPromise.init()isNS_UNAVAILABLE. The standard Objective-C factory methods (resolvedWith:andpromiseWithError:) bridge to Swift as unlabeled static methods that lose type inference. - The Fix: Do NOT attempt to specify generics on the receiver (e.g.,
FBLPromise<Type>.resolved(...)will fail). Instead, call the base method and force-cast the result:// Success return FBLPromise.resolved(response) as! FBLPromise<GACURLSessionDataResponse> // Failure (Must explicitly cast to NSError) return FBLPromise.resolved(error as NSError) as! FBLPromise<GACURLSessionDataResponse>
- PromisesSwift Interoperability: If you need to return an
FBLPromisefrom Swift (e.g., in test mocks), prefer creating a SwiftPromiseand converting it usingasObjCPromise()rather than using reflection or dynamic dispatch:let promise = Promise<GACURLSessionDataResponse>.pending() // ... fulfill or reject ... return promise.asObjCPromise()
The task is not done until a walkthrough.md artifact is created containing:
- Summary of Changes: High-level overview.
- Public API Diff: Any new public APIs.
- Verification Results: Snippets showing successful test runs.
Perform self-reflection after completing the task. You MUST update this file
(agents.md) with any new learnings, context, or troubleshooting steps that
were needed and will be needed again to refine the process for future agents.
Alternatively, create or update a Knowledge Item.