Using the output of a dependent job in the step of another job

I find that in a case where a job, say B, down the dependency tree of another job, say A, with <job.outputs.VAR> needs to explicitly declare the higher job in its needs array to use the outputs as needs.A.outputs.VAR in a steps operation. See a sample snippet

jobs:
  prepare:
    runs-on: ubuntu-latest
    outputs:
      VERSION: pr-1234
    steps:
      - uses: actions/checkout@v2
   build: 
     needs: prepare
     runs-on: ubuntu-latest
     steps: 
        ...
   deploy: 
     needs: build
     runs-on: ubuntu-latest
     steps:
        - uses - actions/checkout@v2
        - echo ${{ needs.prepare.outputs.VERSION }} # This would return empty string ""
...

This only works when I add prepare to the needs array of deploy job := needs: [prepare, build]

If I’m not wrong, this shouldn’t be the case since there’s a dependency chain between deploy and prepare

[EDITED-07/DEC/2021]

I find that for 2 jobs A and B where B is down the dependency tree of A, with A declaring an output <job.outputs.VAR>, then if B needs to use this output in a steps operation, it must explicitly declare A in its needs array. So:

jobs:
  prepare:
    runs-on: ubuntu-latest
    outputs:
      VERSION: pr-1234
    steps:
      - uses: actions/checkout@v2
   build: 
     needs: prepare
     runs-on: ubuntu-latest
     steps: 
        ...
   deploy: 
     needs: build
     runs-on: ubuntu-latest
     steps:
        - uses - actions/checkout@v2
        - echo ${{ needs.prepare.outputs.VERSION }} # This would return empty string ""
...

The deploy job would not get a value for needs.prepare.outputs.VERSION despite having a transitive dependency with prepare. To make this work, one would need to add prepare to the needs array of deploy as so job := needs: [prepare, build]

Is there a reason why this is so?