autonomous-sdlc-harness 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,143 @@
1
+ # harness-trigger.yml — starts an autonomous-sdlc-harness task run when an
2
+ # issue is labelled, or when a `repository_dispatch` asks for one.
3
+ #
4
+ # WHO WRITES IT. `autonomous-sdlc-harness init`, only when harness.config.json's
5
+ # `forge` is `github` and its `execution.target` is `github-actions`. Written
6
+ # create-if-absent: from then on it is yours to tune, and a re-run of `init`
7
+ # keeps your copy. `init --upgrade-workflows` does NOT re-render it: it carries
8
+ # no version pin and calls the scripts on the default branch, so it shares
9
+ # their re-run contract — `init --force` replaces it after a `.bak`.
10
+ #
11
+ # WHAT IT DOES. One job runs `remote-run.sh trigger`, which does everything
12
+ # else: it authorises the start, derives the branch, places and commits the task
13
+ # prompt, pushes, dispatches harness-run.yml, comments on the issue and removes
14
+ # the label. Every decision lives in that script; this file carries only the
15
+ # events, the permissions and the label filter. The `run-name` below is not
16
+ # harness-run.yml's `harness <action> <branch>` title, so no run lookup
17
+ # `remote-run.sh` makes by that title can match a trigger run.
18
+ #
19
+ # THE EVENTS.
20
+ # issues, type `labeled` only, never `opened`: labelling an issue at creation
21
+ # raises `labeled` too, so listening to both would start twice
22
+ # (docs/github-integration-research.md, T1). The job runs only for the
23
+ # label the HARNESS_TRIGGER_LABEL variable names (`harness` when unset);
24
+ # every other label yields a skipped job, which runs no runner and bills
25
+ # nothing (docs/remote-execution.md, `### Verified in Gate 12 round 2`).
26
+ # repository_dispatch, type `harness-task`: the entry for any other adapter
27
+ # (a Jira rule, a script). Its body is
28
+ # {"event_type": "harness-task",
29
+ # "client_payload": {"title": …, "body": …, "source": …}}
30
+ # within GitHub's client_payload limits (10 top-level properties, under
31
+ # 64 KB). Sending one needs a token with Contents write, so its holder is
32
+ # the authority.
33
+ #
34
+ # WHO CAN START A RUN. `remote-run.sh`'s `trigger` paragraph owns the check —
35
+ # the labeller, bots and HARNESS_TRIGGER_ALLOWED_BOTS, the permission call —
36
+ # and the order its refusals are made in. Nothing here pre-filters on it.
37
+ #
38
+ # THE PERMISSIONS, declared because the default token may be read-only
39
+ # (docs/github-integration-research.md, T2):
40
+ # contents: write push the new branch carrying the task prompt
41
+ # actions: write dispatch harness-run.yml and look up the run it created
42
+ # issues: write comment on the issue and remove the trigger label
43
+ # The job reads no repository secret: it needs only its own token, so the
44
+ # credential secrets never reach the job that reads untrusted issue text.
45
+ #
46
+ # THE CHECKOUT. The default branch, with the job's own token and never
47
+ # HARNESS_GIT_TOKEN: a branch pushed with GITHUB_TOKEN starts no workflow
48
+ # (docs/remote-execution.md, `### Verified in Gate 12 round 3`), so the prompt
49
+ # commit does not run your CI. A full fetch, because pushing a new branch from
50
+ # a shallow clone has not been measured anywhere.
51
+ #
52
+ # NO CONCURRENCY GROUP. A group keeps at most one pending run and cancels an
53
+ # earlier pending one, which would drop a trigger. Two starts that race for one
54
+ # branch name are caught by the refused push of an existing branch, and the
55
+ # refusal is commented on the issue.
56
+ #
57
+ # TWO RULES EVERY EDIT KEEPS.
58
+ # * Event text and variables reach a shell line only through `env:` and the
59
+ # event file, never through a GitHub expression inside `run:` — an issue
60
+ # title is written by whoever opened the issue (script injection).
61
+ # * Every GitHub expression has a space after its opening braces. `init`
62
+ # renders its workflows with the CLI's double-brace token renderer, which
63
+ # reads a letter straight after the braces as a token; this file carries
64
+ # no token.
65
+ #
66
+ # DECLARED MIRRORS — a rename on either side is an edit to both:
67
+ # cli/src/remote/githubActions.ts WORKFLOW_TRIGGER_FILE, HARNESS_RUNNER,
68
+ # HARNESS_REMOTE_STOP, HARNESS_TRIGGER_LABEL,
69
+ # DEFAULT_TRIGGER_LABEL (`harness`),
70
+ # HARNESS_TRIGGER_ALLOWED_BOTS,
71
+ # TRIGGER_DISPATCH_EVENT_TYPE (`harness-task`)
72
+ # cli/src/config/model.ts DEFAULTS.scriptsDir
73
+ #
74
+ # ACTION PINS.
75
+ # actions/checkout@v5
76
+ # The lowest major whose own action.yml declares `runs.using: node24`, per a
77
+ # maintainer's lookups of its action.yml and release notes on
78
+ # 2026-09-29T08:21Z (UTC). That major's release notes require Actions Runner
79
+ # 2.327.1 or newer; a GitHub-hosted runner already has it, and a self-hosted
80
+ # one must run it (docs/remote-execution.md, section 8). A major tag, not a
81
+ # commit sha: it is GitHub's own `actions/` organisation, the owner of the
82
+ # runner and GITHUB_TOKEN this job already trusts, and a major tag takes the
83
+ # action's own patch and security releases where a sha would freeze your copy.
84
+ # Pin a sha in your copy if you want one.
85
+
86
+ name: harness-trigger
87
+ run-name: harness trigger ${{ github.event.issue.number || github.event.action }}
88
+
89
+ on:
90
+ issues:
91
+ types: [labeled]
92
+ repository_dispatch:
93
+ types: [harness-task]
94
+
95
+ permissions:
96
+ contents: write
97
+ actions: write
98
+ issues: write
99
+
100
+ defaults:
101
+ run:
102
+ shell: bash
103
+
104
+ jobs:
105
+ trigger:
106
+ if: github.event_name == 'repository_dispatch' || github.event.label.name == (vars.HARNESS_TRIGGER_LABEL || 'harness')
107
+ runs-on: ${{ vars.HARNESS_RUNNER || 'ubuntu-latest' }}
108
+ env:
109
+ GH_TOKEN: ${{ github.token }}
110
+ HARNESS_REMOTE_STOP: ${{ vars.HARNESS_REMOTE_STOP }}
111
+ HARNESS_REMOTE_SLUG: ${{ github.repository }}
112
+ HARNESS_TRIGGER_LABEL: ${{ vars.HARNESS_TRIGGER_LABEL }}
113
+ HARNESS_TRIGGER_ALLOWED_BOTS: ${{ vars.HARNESS_TRIGGER_ALLOWED_BOTS }}
114
+ steps:
115
+ - name: Check out the default branch
116
+ uses: actions/checkout@v5
117
+ with:
118
+ token: ${{ github.token }}
119
+ fetch-depth: 0
120
+
121
+ - name: Check for jq and gh
122
+ run: |
123
+ missing=""
124
+ for tool in jq gh; do
125
+ command -v "$tool" >/dev/null 2>&1 || missing="$missing $tool"
126
+ done
127
+ if [ -n "$missing" ]; then
128
+ echo "::error::this runner lacks:$missing. Install them on the self-hosted runner, or use a GitHub-hosted one."
129
+ exit 1
130
+ fi
131
+
132
+ - name: Read the configuration
133
+ run: |
134
+ scripts_dir=$(jq -r '.scriptsDir // "scripts"' harness.config.json)
135
+ echo "SCRIPTS_DIR=${scripts_dir%/}" >> "$GITHUB_ENV"
136
+
137
+ - name: Set the git identity
138
+ run: |
139
+ git config user.name "github-actions[bot]"
140
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
141
+
142
+ - name: Start the run
143
+ run: bash "$SCRIPTS_DIR/remote-run.sh" trigger
@@ -68,5 +68,10 @@
68
68
  # rule a wired repository carries an untracked file from its first `config set` onward. The leading
69
69
  # slash anchors it at the repository root, the only place the configuration is written.
70
70
  /{{configBackupFile}}
71
+ # The copies `init --upgrade-workflows` and `init --force` take of the two remote-execution workflows
72
+ # and of the permission profile. The upgrade's report names each workflow copy in a diff command, and
73
+ # the profile copy carries this machine's absolute paths just as the profile does. Every other .bak a
74
+ # forced run writes is left visible on purpose.
75
+ {{harnessBackups}}
71
76
  {{qaBrowserArtifacts}}
72
77
  {{docsRetrievalIndex}}