docs(P04): research findings — pipeline topology, gates, state persistence
---ci---
phase: 4
milestone: v1.0
status: research
research:
gitea_actions_capabilities:
upload_artifact_v3: supported (v4 NOT supported by act_runner)
artifacts_cross_dispatch: NOT preserved (re-dispatch starts a new run)
workflow_dispatch_api: POST /actions/workflows/{filename}.yml/dispatches
workflow_call: supported; uses: <owner>/<repo>/.gitea/workflows/<file>@<ref>
checkout_cross_repo: actions/checkout@v4 with repository + ref + token
secrets: ${{ secrets.GITEA_TOKEN }} must be a manually-created PAT (auto-token is current-repo only)
approval_gate: workflow_dispatch input (approve_qa, approve_prod); no native pause-and-wait
pipeline_design:
topology: single pipeline.yml with workflow_dispatch inputs (contract-ref, approve_qa, approve_prod)
stages: 3 separate dispatches (initial dev, qa-approve, prod-approve+finalize)
state_persistence: each stage writes evidence to acdl-evidence via file-contents API (PUT audit.json)
job_if_conditions: dev runs when !approve_qa && !approve_prod; qa-gate when approve_qa && !approve_prod; prod-gate+finalize when approve_prod
personas: no change; backend-engineer owns the workflow YAML + finalize + issue trigger; lead-developer owns verify_phase04.sh
---/ci---
ARCHITECTURE.md gains a 'Phase 04 pipeline topology (research)' section:
the artifact-vs-re-dispatch limitation forces 3-dispatch topology with
evidence persisted to acdl-evidence (PUT audit.json) between dispatches.
PERSONAS.md is unchanged for Phase 04 (backend-engineer + lead-developer
active; infra-stub-engineer idle; frontend-engineer still off).
This commit is contained in:
@@ -49,6 +49,47 @@ The demo is a three-repo, stub-driven system that simulates an autonomous cloud
|
||||
| `acdl-evidence` repo | Pages host for `audit.json` + `index.html` timeline | Read-only for the pipeline; written at finalize stage | evidence_writer.py output |
|
||||
| Reusable pipeline workflow | Dev → QA → Prod → Finalize stages with environment gates | Gitea Actions; calls core scripts | All core scripts |
|
||||
|
||||
## Phase 04 pipeline topology (research)
|
||||
|
||||
Gitea Actions limitations (confirmed via research, supersedes any
|
||||
GitHub-Actions assumptions):
|
||||
|
||||
- `actions/upload-artifact@v3` / `download-artifact@v3` work; v4 is NOT supported by act_runner.
|
||||
- Artifacts are scoped to a single workflow run; **re-dispatch starts a new run, so artifacts do NOT survive between dispatches**.
|
||||
- `workflow_dispatch` API: `POST /api/v1/repos/{owner}/{repo}/actions/workflows/{filename}.yml/dispatches` with body `{ "ref": "<branch>", "inputs": {...} }`.
|
||||
- `on: workflow_call` + `uses: <owner>/<repo>/.gitea/workflows/<file>@<ref>` works; pin to `@milestone/v1.0-initial`.
|
||||
- `actions/checkout@v4` supports cross-repo (pass `repository:` + `ref:` + `token: ${{ secrets.GITEA_TOKEN }}` for private repos).
|
||||
- File-contents API: POST to create (201), PUT to update (must include current `sha`, obtained via GET).
|
||||
- `${{ secrets.GITEA_TOKEN }}` is a manually-created PAT secret on the `acdl` + `acdl-contracts` repos; the auto-injected token is current-repo only and cannot cross-repo.
|
||||
- No native approval-gate UI; gates are `workflow_dispatch` inputs (`approve_qa`, `approve_prod`).
|
||||
|
||||
### Approval-gate + state-persistence approach (D-027, D-028 refined)
|
||||
|
||||
Because re-dispatch starts a new run and artifacts do not survive:
|
||||
|
||||
1. The pipeline workflow has `workflow_dispatch` inputs:
|
||||
- `contract-ref` (string; default `main`) — the ref on `acdl-contracts` carrying the contract.
|
||||
- `approve_qa` (boolean; default `false`) — the human sets this to `true` to advance past QA.
|
||||
- `approve_prod` (boolean; default `false`) — the human sets this to `true` to advance past Prod.
|
||||
|
||||
2. Each stage job (`dev`, `qa-gate`, `prod-gate`, `finalize`) writes its evidence to `acdl-evidence` via the file-contents API (PUT `audit.json` with the new event appended). This is the persistent state across re-dispatches.
|
||||
|
||||
3. **Dev stage** (always runs on dispatch): check out `acdl` + `acdl-contracts@<contract-ref>`, run `policy_checker.py` + `confidence_signal.py`; if `score < 0.50`, write a `dev_rejected` evidence event and exit 1 (Act 4). Otherwise run `mock_executor.sh`, write a `dev_applied` evidence event, and exit 0. The run ends here.
|
||||
|
||||
4. **QA gate** (next dispatch with `approve_qa=true`): check out, run `evidence_writer.py --stage qa --event "qa approved"`, commit updated `audit.json` to `acdl-evidence`. Exit 0. The run ends.
|
||||
|
||||
5. **Prod gate** (next dispatch with `approve_prod=true`): same as QA but `--stage prod`.
|
||||
|
||||
6. **Finalize** (same dispatch as Prod, chained via `needs: prod-gate`): write the `finalize` evidence event, commit final `audit.json` to `acdl-evidence`. The raw URL now serves the updated timeline.
|
||||
|
||||
Because each stage is a separate dispatch, the workflow file uses `if:` conditions on each job:
|
||||
- `dev` runs when `inputs.approve_qa != true && inputs.approve_prod != true` (the initial dispatch).
|
||||
- `qa-gate` runs when `inputs.approve_qa == true && inputs.approve_prod != true`.
|
||||
- `prod-gate` runs when `inputs.approve_prod == true`.
|
||||
- `finalize` runs after `prod-gate` (`needs: prod-gate`).
|
||||
|
||||
This means a full pipeline = 3 dispatches (initial, qa-approve, prod-approve). The human drives each via the Gitea UI or the dispatch API.
|
||||
|
||||
## Data Flow
|
||||
|
||||
1. A `contract.yaml` arrives either by direct push (L3A) or by the issue workflow running `l3b_agent_stub.py` (L3B).
|
||||
|
||||
Reference in New Issue
Block a user