TLDR overview
- Gitar Cross-Repo Analysis can expose contract breaks across repositories during pull request review, before the change merges.
- Repository CI can pass while a separate client still calls an API route the service removed.
- Gitar works out which repositories are likely affected without a manually maintained list of consumers.
- The Gitar cross-repo finding shows where the break lands and offers a way to keep the old contract working while clients migrate.
Overview
By the end of this blueprint, you’ll update a shared deployment workflow to require write access, then see Gitar identify and flag the service that still uses read-only permissions in the pull request, all before it merges. Gitar produces the finding through Cross-Repo Analysis, which checks pull requests against other repositories in your organization and discovers how they relate to each other. Gitar does this on its own, so you never link repositories by hand or maintain a list of consumers. You'll also see how this analysis catches an image whose drain budget exceeds the Kubernetes termination deadline in a sibling Helm chart.
When to use this
Use this blueprint when two or more repositories share a contract, such as an HTTP route, a response field, an event name, etc. A producer app that moves /api/v1/orders/<order_id> to v2 and updates its own tests might pass CI while the consumer app keeps calling the old path. This could unfortunately cause the issue to remain invisible until the producer deploys, that is, unless something reads both repositories during review.
What you'll achieve
- Cross-Repo Analysis enabled for your Gitar organization
- A
Cross-Repofinding on a shared workflow's permission change, naming the calling service's workflow file, job, and incompatible grant - The Helm chart's
terminationGracePeriodSecondsflagged as incompatible with a worker's raised drain budget, with the finding explaining the interrupted-task consequence - A dashboard view of the connections between producers and their consumers
Architecture

Gitar creates a repository summary the first time it reviews a repository and refreshes that summary as the repository changes, and those summaries are what it uses to decide which repositories a pull request can reach. When a pull request opens or receives a push, Gitar narrows the organization down to the repositories that the change likely affects, reads the relevant files in each of them to verify that the impact is real, and reports verified impacts as findings on the pull request line that changed the contract. Relationships aren't limited to imports or shared packages, since the documented contract types include route paths, wire fields, enum values, event names, error codes, database columns, CI workflows, base images, file layouts, and versioned contracts.
Findings from this pass carry the Cross-Repo category and post inline alongside Gitar's other review findings. They also appear in the pull request's dashboard comment, and organization admins get a Cross-repo view in the Gitar dashboard where they can see which repositories are connected and filter findings by repository, status, or the side where the fix belongs.
Prerequisites
- A Gitar organization on the Enterprise plan (Gitar plans)
- The organization admin role in Gitar, which gives you access to the Cross-repo dashboard and its toggle
- At least two GitHub repositories for the primary walkthrough, with the Gitar app installed on both and permission to open and merge pull requests. Cross-Repo Analysis also supports GitLab, Azure DevOps, Bitbucket Cloud, and Bitbucket Data Center (platform support).
- For the workflow permissions walkthrough: one repository with a reusable GitHub Actions workflow and one repository whose release or deployment pipeline calls it
Step 1: Cross-Repo Analysis enabled for the organization
New Enterprise organizations get Cross-Repo Analysis turned on by default, although an organization that joined Enterprise earlier may still have it off. Go to Dashboard -> Cross-repo in Gitar and check that the Cross-repo toggle is on, which enables the feature for every repository in the organization at once.

Step 2: Shared workflow and caller that Gitar has already reviewed
The producer is a shared deployment workflow repository that other services call through workflow_call. A workflow in .github/workflows/deploy.yml verifies a release bundle, registers a staging deployment, and currently requests statuses: read:
# <ORG>/release-workflows/.github/workflows/deploy.yml
on:
workflow_call:
inputs:
version:
required: true
type: string
artifact-name:
required: true
type: string
permissions:
contents: read
actions: read
deployments: write
statuses: read The consumer is a payments service whose release pipeline calls this workflow. Its deploy job grants the same statuses: read that the shared workflow currently expects:
# <ORG>/payments-service/.github/workflows/release.yml
deploy:
needs: package
permissions:
contents: read
actions: read
deployments: write
statuses: read
uses: <ORG>/release-workflows/.github/workflows/deploy.yml@main
with:
version: ${{ inputs.version }}
artifact-name: payments-bundle Neither repository imports the other as a code dependency or declares a package relationship, so the only connection is the uses: reference in the caller workflow and the permission contract it implies.
Coverage builds as Gitar reviews repositories, so give each repository at least one review before you test a contract change. Open a small pull request in each repository, wait for Gitar to finish reviewing it, and merge it. A README edit is enough:
git checkout -b warm-up/initial-review
# make a small edit to README.md
git commit -am "Add ownership documentation"
git push -u origin warm-up/initial-review
gh pr create --fillExpect each warm-up review to a few minutes. After the last one completes, open the Review activity tab on the Cross-repo dashboard and confirm that every repository appears in the list.

Step 3: Shared workflow requiring elevated permissions
Create a branch in the shared workflow repository for a broader change that adds deployment status reporting. The pull request adds pending and final release/staging commit statuses, captures the deployment ID, writes a release summary, and raises the workflow's permission from statuses: read to statuses: write so the new reporting steps can post status checks:
git checkout -b feature/deployment-status-reportingThe permission change in the diff is one line among several files of deployment-reporting work:
permissions:
contents: read
actions: read
deployments: write
- statuses: read
+ statuses: writePush the branch and open a pull request. The workflow is valid YAML, the new reporting steps are correct, and any local validation passes, because the permission escalation only matters when a caller with a lower grant tries to invoke the updated workflow.
git push -u origin feature/deployment-status-reporting
gh pr create --title "Add deployment status reporting and release summaries" --fillStep 4: A Cross-Repo finding on the permission mismatch
Gitar posts its review shortly after the pull request opens.

Gitar explains that the calling service's deploy job in .github/workflows/release.yml still grants only statuses: read, and that in a workflow_call a nested job cannot receive more permissions than its caller grants. GitHub rejects the run when it starts with "nested job is requesting statuses: write, but is only allowed statuses: read," so the payments service release fails before verification or deployment registration runs. Even if the run were allowed to start, the createCommitStatus calls in the new reporting steps would return 403.
The finding recommends coordinating the permission change: merge the shared workflow update only after callers update their grants, or publish the change under a new version or tag so existing callers continue to call the current contract. On the consumer side, the fix is changing the deploy job's permissions from statuses: read to statuses: write.
Step 5: Coordinate the fix before merging
The finding lays out two paths. You can update the consumer's grant first, changing statuses: read to statuses: write in the payments service's deploy job and merging that before the shared workflow change ships. Or you can publish the updated workflow under a new tag or version so existing callers continue to use the current contract until they opt in. Either way, the key is that you know about the incompatibility before the shared workflow merges, while both sides are still open for coordination rather than broken in production.
A second contract type: worker drain budget versus Helm termination deadline
The same analysis catches contracts that span application configuration and deployment infrastructure. A batch worker that processes invoice aggregation tasks handles SIGTERM with a bounded drain, while a Helm chart in a sibling repository deploys the same image with terminationGracePeriodSeconds: 60.
The worker's baseline configuration gives it 45 seconds to drain, which fits comfortably within the chart's 60-second deadline:
# batch-worker/src/batch_worker/config.py (baseline)
SHUTDOWN_GRACE_SECONDS = float(os.environ.get("SHUTDOWN_GRACE_SECONDS", "45"))
MAX_TASK_SECONDS = 40
LEASE_SECONDS = 120The Helm chart's values file sets the pod termination deadline:
# batch-worker-deploy/charts/batch-worker/values.yaml
terminationGracePeriodSeconds: 60A pull request titled "Add regional settlement aggregation and longer processing windows" raises the drain budget from 45 to 180 seconds and the task window from 40 to 150 seconds to support longer settlement operations. The change spans seven files, including regional aggregation logic, a version bump, and updated tests. The drain budget increase is embedded in the feature work:
# batch-worker/src/batch_worker/config.py (PR)
SHUTDOWN_GRACE_SECONDS = float(os.environ.get("SHUTDOWN_GRACE_SECONDS", "180"))
MAX_TASK_SECONDS = 150
LEASE_SECONDS = 240The worker's tests pass, the Dockerfile builds, and the publication workflow validates the bundle, because nothing in the worker's own pipeline checks the deployment chart. Gitar posts a Cross-Repo finding on the configuration line, naming batch-worker-deploy, charts/batch-worker/values.yaml, and terminationGracePeriodSeconds:

The finding explains that on a rollout or eviction, Kubernetes sends SIGTERM and then SIGKILL at 60 seconds, which cuts off a 90-to-150-second regional settlement mid-task before the result is stored and acknowledged. The interrupted task then waits for the 240-second lease to expire before another worker recovers it, so the graceful drain that the PR documents never actually happens under the current chart. Because the publication workflow pushes the mutable :main tag, merging the worker PR changes running pods' behavior on their next restart even if the chart stays the same.
Gitar recommends merging the worker PR only after raising the chart's terminationGracePeriodSeconds to at least the drain budget plus shutdown overhead.
Cross-Repo Analysis also catches application-layer contract changes
Beyond CI workflows and deployment configuration, Cross-Repo Analysis identifies breaking API contracts between services. Renaming GET /api/v1/orders/<order_id> to v2 in a Flask producer, while updating only the producer's own tests, surfaces a finding that names the consumer's order_client.py and the fetch_order_summary function that still builds its request from the old path. The finding explains that raise_for_status() will throw after the v1 route disappears, and it offers a fix on each side: a v1 alias on the producer to hold the contract while consumers migrate, or a one-line path update in the consumer.
Verify the setup
Open Dashboard -> Cross-repo and check the Findings tab. Each finding's detail panel shows the repository where the change was made, the repository it could affect, and an expandable Technical details section with the changed file, affected file, and fix-location labels. The connection view at the top of the page draws lines between connected repositories, and selecting a producer node shows its outgoing findings and connected consumers.


The workflow permissions finding shows the permission mismatch between release-workflows and payments-service, with fix labels on both sides. The drain budget conflict between batch-worker and batch-worker-deploy appears the same way, with the chart's terminationGracePeriodSeconds in the affected-file position.
What to know
Gitar creates a repository summary the first time it reviews a repository and refreshes it as the repository changes, and there is no enrollment step or backfill to run. A review opened right after you enable the feature may not reach every relevant repository yet, and a trivial pull request in any repository Gitar hasn't reviewed is enough to bring it into coverage.
Cross-Repo Analysis is available only on Enterprise, and the Cross-Repo category does not appear in reviews unless the feature is enabled for the organization. Relationships can span code hosts, so a service on GitHub and a client on GitLab can be checked together.
Some relationships never appear in code, such as a data job that reads your tables or an archived repository you want Gitar to ignore, and you can name them in a natural-language .gitar/cross-repo.md file in one repository or in a configuration repository for organization-wide guidance, as described in the Cross-Repo Analysis documentation.
Turning the Cross-repo toggle off stops future processing but keeps the findings and history already collected, so switching it back on later does not start you from an empty dashboard. Gitar skips code review for a pull request that contains only one revert commit, although CI analysis and rule evaluation still run, and a later commit makes the pull request eligible for review again.
Next steps
- Gitar code review for finding categories, severity levels, and how the dashboard comment tracks resolved findings
- Gitar context ingestion for project-aware code reviews for repository instructions and rules that shape every Gitar review
- Scale Gitar context across an organization for organization instructions and external context from Jira and Slack
