How can I avoid a Terraform plan being run in quick succession?

Our terraform CI/CD works fine, in the sense the plan is run in the MR. And merged to main, it again plans and applies.

But there lies the problem, if there is an existing tfplan, why plan AGAIN in the main branch job ?

stages:
  - plan
  - apply
dev-01-acm-internal:plan:
  stage: plan
  variables:
    TF_PROJECT_DIR: stacks/backend/01-acm-internal
    PLAN_JSON: $CI_PROJECT_DIR/stacks/backend/01-acm-internal/plan.json
  script:
    - cd stacks/backend/01-acm-internal
    - rm .terraform/terraform.tfstate || true
    - internal-assume-role
    - aws sts get-caller-identity
    - make -f $CI_PROJECT_DIR/Makefile init env=dev account=backend
    - make -f $CI_PROJECT_DIR/Makefile providers-lock plan
    - terraform show --json tfplan | convert_report > $PLAN_JSON
  artifacts:
    paths:
      - $TF_PROJECT_DIR/tfplan
      - $TF_PROJECT_DIR/.terraform
      - $TF_PROJECT_DIR/.terraform.lock.hcl
    reports:
      terraform: $PLAN_JSON
  rules:
    - changes:
        - stacks/backend/01-acm-internal/dev.tfvars
dev-01-acm-internal:apply:
  stage: apply
  variables:
    TF_PROJECT_DIR: stacks/backend/01-acm-internal
  script:
    - internal-assume-role
    - cd stacks/backend/01-acm-internal
    - make -f $CI_PROJECT_DIR/Makefile apply
  needs:
    - job: dev-01-acm-internal:plan
      artifacts: true
  rules:
    - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
      changes:
        - stacks/backend/01-acm-internal/dev.tfvars
      when: on_success
      allow_failure: false
  environment:
    name: dev

How can I make dev-01-acm-internal:apply: only run on the merge to main. I.e. if the $TF_PROJECT_DIR/tfplan is present in the cache (which it should be iiuc), skip the dev-01-acm-internal:plan: job, as it’s unnecessary.

Any other suggestions would be great. Incidentally this is code generated across many several stacks using dynamic child pipelines.