git:20261023.769a667 to git:20261023.a914ac2

65 added, 68 removed. Audit A to A.

---
name: harness-contributing
description: Contribute a public change to Harness Anything from a GitHub issue through an isolated worktree, scoped tests, manifest-selected gates, a complete PR body, review triage, and maintainer merge. Use when a human or coding agent is preparing or updating a contribution to this repository.
---
# Harness Contributing
This is the executable contribution path for this repository. Start with a
public issue or a maintainer-approved scope, work in one isolated worktree, and
finish with a reviewable pull request. The current
[`tools/gate-manifest.json`](../../tools/gate-manifest.json),
[`package.json`](../../package.json), and
[`pull_request_template.md`](../../.github/pull_request_template.md) remain the
machine-readable authorities they describe; inspect them instead of relying on
remembered job names or template fields.
## Boundary
Use only public repository source, public issue/PR discussion, and evidence a
reviewer may see. Never copy local planning records, generated runtime state,
local agent instructions, credentials, private URLs, or absolute machine paths
into the branch or PR body. Before every commit, inspect the complete staged
diff and confirm every path belongs to the stated public scope.
The contribution scope grants authority to change the stated files and run
local checks. Push the branch or open/update its PR only when the user or
maintainer asked for that external action. No contribution grants authority to
push to `main`, bypass a gate, force-push, or merge. A maintainer owns the final
merge.
> 中文:只使用公开仓库、公开 issue/PR 和 reviewer 可见的证据。不要把本地规划、
> 运行状态、凭证、私有链接或本机绝对路径放进公开 diff 或 PR。贡献者只能提交提案,
> 不能直推或自行合入 `main`。
## Environment and worktree
Node.js 24 or newer and git are required. For a new checkout, run:
```bash
git clone https://github.com/FairladyZ625/harness-anything.git
cd harness-anything
git fetch origin
git status --short --branch
```
Run this version gate as one standalone command before `npm ci`; it exits
nonzero and prints three common activation choices when the active Node is too
old:
```bash
node -e 'const major=Number(process.versions.node.split(".")[0]); if (major < 24) { console.error([`Node.js 24+ required; found ${process.version}.`, "nvm: nvm install 24 && nvm use 24", `Homebrew node@24: brew install node@24 && export PATH="$(brew --prefix node@24)/bin:$PATH"`, "Volta: volta install node@24"].join("\n")); process.exit(1); } console.log(`Node.js ${process.version} satisfies >=24`);'
```
If it fails, use one printed line to activate Node 24, then rerun the same gate
until it exits zero. Stop if the checkout already has changes you do not own.
Do not implement on the primary checkout or shared `main`. From the primary
checkout, create exactly one task worktree from current `origin/main`:
```bash
git worktree add .worktrees/<slug> -b <branch> origin/main
cd .worktrees/<slug>
git merge-base --is-ancestor origin/main HEAD
git rev-list --count origin/main..HEAD
git log --oneline origin/main..HEAD
git status --short --branch
npm ci
```
Replace `<slug>` with a short filesystem-safe scope and `<branch>` with the
public contribution branch, such as `fix/<slug>` or `docs/<slug>`. If either
name already belongs to another worktree, choose a new name; never share that
worktree. `git merge-base --is-ancestor` must exit zero before editing. A newly
created branch should print `0` from `git rev-list` and no commit lines from
`git log`. Any listed commit is already part of the prospective
`origin/main...HEAD` PR delta: continue only when it belongs to the approved
public contribution, and later describe the whole branch delta while clearly
distinguishing those pre-existing commits from the edits made in this run.
Otherwise stop and create a clean worktree or ask the maintainer which branch
scope is intended.
Read the issue and relevant source in this worktree. State, in one sentence,
the problem, allowed change surface, excluded surface, and proof required. Ask
for a maintainer decision rather than guessing when the public issue does not
settle a load-bearing choice.
> 中文:先用单独的一条可执行命令确认 Node 24+,再从最新 `origin/main` 创建独立
> worktree;每个贡献者或 agent 使用自己的 branch/worktree。编辑前列出 ahead
> commit;它们会进入整个 PR diff,不能当作不存在。安装依赖并写清范围后再编辑。
## Make the change and test its surface
Keep the patch to the smallest coherent solution. Inspect nearby code and tests
before adding a new abstraction. Preserve unrelated changes and generated
files.
Every new Node test under `packages/` or `tools/` must:
- have a filename ending in `.test.mjs`, `.test.js`, `.test.ts`, `.spec.mjs`,
`.spec.js`, or `.spec.ts`; and
- put exactly one of these declarations on line 1:
```js
// harness-test-tier: fast
// harness-test-tier: contract
// harness-test-tier: integration
```
Choose `fast` for pure or near-pure behavior, `contract` for public API/schema
or cross-package contracts, and `integration` for CLI, filesystem, store,
migration, or other slower behavior. The rules are enforced by
[`tools/test-tier-manifest.mjs`](../../tools/test-tier-manifest.mjs); there is no
central file list to edit.
Run changed or newly added fast tests through the repository runner:
```bash
node tools/run-node-tests.mjs --file <repo-relative-test-file>
```
Run the tests affected by the change with the repository runner. Internal server
dispatch is provided by the private `test-isolation` skill and is not part of this
public contribution skill:
```bash
node tools/run-node-tests.mjs --tier fast
```
`--changed <base>` (default `origin/main`) selects the test files the committed change
itself edits, plus the registered test files whose imports reach a changed source; the
import scan is a heuristic, so use it as the default sweep before handing off. When a
change touches a shared surface — authorization, settings, construction entry points,
protocol, or events — run the owning package's whole tier instead of the scan:
```bash
node tools/run-node-tests.mjs --tier integration --prefix packages/daemon/test
```
Exact files and the other tiers take the same selector:
```bash
node tools/run-node-tests.mjs --file tools/run-node-tests.test.mjs
```
For a docs-only change, run the closest docs checker or checker test if one exists; do
not invent a meaningless test. Always inspect the patch:
```bash
git status --short
git diff --check
git diff --stat
git diff -- <changed-paths>
```
> 中文:测试文件名必须匹配 `.test`/`.spec` 约定,首行必须且只能声明一个
> `fast|contract|integration` tier。本机先跑改动面的精确测试;交给测试服务器用
> `node tools/run-node-tests.mjs --tier fast` 运行通用本机测试。改动碰到
> 授权、settings、构造入口、协议、事件这类共享路径时,改用
> `node tools/run-node-tests.mjs --tier integration --prefix packages/<包>/test` 跑所在包整层。docs-only 改动若没有
> 对应行为测试,不要为了凑数新增无意义测试。
- ## Run local gates
+ ## Run local static gates before you push
Do not use `npm run check:local` as the contribution loop, and do not run the
- full aggregate merely to approximate GitHub. GitHub CI is authoritative. The
- worker stop-point command derives its cheap deterministic checks from the
- current gate manifest and the complete working-tree diff:
+ full aggregate merely to approximate GitHub. GitHub CI is authoritative. But a
+ boundary/vocabulary/dead-export/write-path/complexity red costs an ~11 minute CI
+ round trip, and those gates read only repository source. Run them locally before
+ the commit:
```bash
- node tools/run-manifest-gates.mjs --changed origin/main
+ npm run check:static # the whole static set, ~75s
+ npm run check:static -- --changed # only gates whose localPathGlobs match the working-tree diff
```
- Run that command before the local commit. It includes every matching gate whose
- manifest entry is deterministic, local, PR-visible, and declares
- `localPathGlobs`; an unscoped gate is not silently promoted into this bounded
- local path. Run affected integration tests separately through the isolated test
- dispatcher. Use `--workflow-job` only to reproduce or preflight a particular CI
- job; workflow mode runs all selected gates and reports every failure together.
+ The set is derived from `tools/gate-manifest.json`, not a second checklist: a
+ gate qualifies when it is `deterministic: true`, PR-visible, `pr-required`, and
+ neither a test tier, a smoke, nor a release-policy gate. That deliberately leaves
+ out three things a worker must not run here:
- First list the current pull-request job names and tiers:
+ - **Gates that need inputs this machine does not own.** `deterministic: false`
+ gates read external APIs, so on a clean worktree they fail with e.g.
+ `repository must be provided as owner/name`. Selecting them is what made the
+ old local gate command red on unmodified code.
+ - **Test tiers and smokes.** `test:fast`, `test:contract`, `test:integration`,
+ `test:gui` and the package smokes run whole tiers or boot a packaged artifact;
+ run only the tests your change affects instead (see above), and let CI own the
+ full tiers.
+ - **Release-policy gates.** `check-package-tarball-exports` alone spends ~99s
+ packing tarballs for a verdict a static read cannot give.
- ```bash
- node -e 'const m=require("./tools/gate-manifest.json"); console.log([...new Set(m.gates.filter(g=>!g.aggregate).flatMap(g=>(g.executionSurfaces?.rewriteCi?.pullRequestJobs??[]).map(job=>`${g.tier}\t${job}`)))].sort().join("\n"))'
- ```
+ `--changed` narrowing is a convenience, not a licence to skip: a gate that
+ declares no `localPathGlobs` cannot be narrowed and always runs. When the diff
+ touches a shared surface (protocol, events, authorization, construction
+ entry points), run the full set and the affected integration files through the
+ isolated test dispatcher.
- Then print the gate IDs, commands, and declared consumer scope behind those
- jobs; use this output rather than inferring a job from its name:
+ To reproduce a specific CI job instead, list its gates and run the job with the
+ manifest runner. `--workflow-job` runs every selected gate and reports all
+ failures together; CI omits `--changed` and still runs every command:
```bash
node -e 'const m=require("./tools/gate-manifest.json"); for (const g of m.gates.filter(g=>!g.aggregate)) for (const job of g.executionSurfaces?.rewriteCi?.pullRequestJobs??[]) console.log(`${job}\t${g.id}\t${g.command}\t${(g.consumerScope??[]).join("; ")}`)'
- ```
-
- Then run every job that matches the changed surface. Pass the merge base to the
- runner so its optional manifest path declarations can narrow local commands; a
- working-tree comparison includes committed, uncommitted, and untracked edits:
-
- ```bash
node tools/run-manifest-gates.mjs --workflow-job <job> --changed origin/main
- npm run typecheck
```
`boundaries` is the usual job for public source, tool, and documentation
boundaries. Use the manifest's other current PR jobs when the patch touches
their surface—for example tests, package policy, dependencies/supply chain, or
- the GUI. Path selection is conservative: it narrows a job only when every
+ the GUI. Job-level path selection is conservative: it narrows only when every
changed path matches explicit `localPathGlobs`; an unclassified or mixed surface
- runs the complete job. A docs-only change under `docs-release/**` selects the
- three docs/release checks declared by the manifest. CI omits `--changed` and
- still runs every command in every job. Record every command and result in the PR
- body, including a scoped reason for anything not run.
+ runs the complete job. Record every command and result in the PR body, including
+ a scoped reason for anything not run.
- One gate has a local credential exception. If `boundaries` reaches
- `check-github-required-contexts`, the only failure that may be excluded locally
- is the exact error `repository must be provided as owner/name` when no GitHub
- repository/token context is available. Preserve that output and rerun the same
- job with only that gate excluded:
+ If a `--workflow-job` run reaches `check-github-required-contexts`, the only
+ failure that may be excluded locally is the exact error
+ `repository must be provided as owner/name` when no GitHub repository/token
+ context is available. Preserve that output and rerun with only that gate
+ excluded:
```bash
node tools/run-manifest-gates.mjs --workflow-job boundaries --changed origin/main --exclude check-github-required-contexts
```
If that exact message is not the sole failure, do not exclude the gate. Never
treat the exclusion as a CI waiver; the required GitHub context must still pass
- on the PR.
+ on the PR. `npm run check:static` needs no such exception because it excludes
+ every non-deterministic gate by declaration.
- > 中文:worker 停止点统一运行 `node tools/run-manifest-gates.mjs --changed
- > origin/main`;它从 manifest 中派生带 `localPathGlobs` 的本地、PR、确定性门,不维护
- > 第二份清单。受影响的 integration 测试仍须经隔离派测入口单独运行。按 job 复现 CI
- > 时才使用 `--workflow-job`,该模式会跑完所选门并一次报告全部失败;CI 始终全跑。
- > 本地只有 `check-github-required-contexts` 的精确报错
- > `repository must be provided as owner/name` 可在确认缺 GitHub 上下文后单独排除;
- > 该排除不适用于 CI,也不能掩盖其他失败。
+ > 中文:推送前跑 `npm run check:static`(全套约 75s)或加 `--changed` 只跑与改动
+ > 相关的门。集合由 `tools/gate-manifest.json` 派生:`deterministic: true`、PR 可见、
+ > `pr-required`,且不是测试层、smoke 或 release-policy 门。刻意不含三类——需要本机
+ > 没有的外部输入的 `deterministic: false` 门(它们会在干净 worktree 上报
+ > `repository must be provided as owner/name`)、整层测试与 smoke、以及打包类
+ > release-policy 门(仅 `check-package-tarball-exports` 就要约 99s)。`--changed`
+ > 是便利不是豁免:未声明 `localPathGlobs` 的门无法收窄,永远运行。触碰协议、事件、
+ > 授权、构造入口这类共享面时跑全套,并按隔离入口点名受影响的 integration 文件。
+ > 这是 worker 的本地静态门,不是 `check:local`;CI 仍是完整权威。
## Commit with the contributor identity
Confirm the author identity before committing:
```bash
git config --get user.name
git config --get user.email
```
If either is empty or wrong, the contributor must set their own identity before
continuing:
```bash
git config user.name "<your name>"
git config user.email "<your email>"
```
Stage only named contribution paths, recheck the staged patch, and commit:
```bash
git add <changed-paths>
git diff --cached --check
git diff --cached --stat
git diff --cached -- <changed-paths>
git commit -m "<feat|fix|refactor|docs|test|ci>: <concise English summary>"
```
Do not mention an AI author in the commit message. Use the actual human or
agent operator's configured git identity.
## Prepare the PR body
- Do this after all contribution commits and after `ha task submit` freezes the
- delivery cut. Refresh and synchronize first, then rerun affected tests and
- resubmit if a rebase changes the branch:
+ Do this after all contribution commits, because the production-delta gate
+ measures committed `HEAD` from its merge-base. Refresh and synchronize first,
+ then rerun affected tests and gates if the rebase changes the branch:
```bash
git fetch origin
date -u '+%Y-%m-%d %H:%M:%S UTC'
git rebase origin/main
git rev-parse origin/main
git merge-base origin/main HEAD
git status --short --branch
```
If the initial worktree check found approved pre-existing commits, describe the
complete `origin/main...HEAD` delta in the PR body and explicitly separate
those commits from the changes authored in the current run.
- Generate the body from the live template and frozen submission; the generated
- Delivery Facts block owns the commit, merge base, changed paths, and production
- delta. Never hand-copy those values:
+ Copy the current template; never reconstruct its sections from memory:
```bash
- node tools/gates/render-task-pr-body.mjs --task <task-id> > /tmp/harness-anything-pr-body.md
+ cp .github/pull_request_template.md /tmp/harness-anything-pr-body.md
${EDITOR:-vi} /tmp/harness-anything-pr-body.md
```
- Fill the human-authored sections with real delivery facts. Keep the generated
- Delivery Facts block intact. After an amended submission, rerun the renderer
- against the current body file so the block follows the new frozen cut:
-
- ```bash
- node tools/gates/render-task-pr-body.mjs --task <task-id> --body-file /tmp/harness-anything-pr-body.md > /tmp/harness-anything-pr-body.next.md
- mv /tmp/harness-anything-pr-body.next.md /tmp/harness-anything-pr-body.md
- ```
-
- Governance
+ Fill every uncommented section with real delivery facts. Governance
Declaration and the Dependency-Change line are required only when their
trigger applies — a manifest-derived protected surface is touched, or a
package manifest or lockfile changes; otherwise the template defaults are
complete. Do not claim CI, human review, or a test that has not happened.
Reference the public issue number in the Summary section, for example
`#1234`. Never put a private task ID, local planning ID, or private evidence
path in the public PR body. If neither `package.json` nor
`package-lock.json` changed, delete the entire `Dependency-Change:` line; do
not leave `Dependency-Change: none`. Keep and fully describe that line only
when one of those dependency files changed.
In Verification, record a command only when its exact command exited zero,
either because you ran it directly or because the manifest runner printed
that command and reported it passed. A passing current `boundaries` job
indirectly runs `npm run harness:check-import-boundaries`,
`npm run harness:scan-forbidden-symbols`,
`npm run harness:check-private-boundary`,
`npm run harness:check-implementation-contracts`,
`npm run harness:check-schema-contracts`, and
`npm run harness:check-legacy-intake-readiness`; list anything else that was
not run with a reason.
- Do not calculate or hand-copy production delta into the body. The submission
- freezes G33's result for its delivery commit; the PR renderer inserts it, and
- the PR workflow independently runs G33 against the current delivery diff.
+ Run the authoritative production-delta calculator after all commits. It
+ reports the computed addition, deletion, churn, and net values from the diff
+ alone — no PR body declaration is involved:
+ ```bash
+ node tools/gates/production-delta.mjs --base origin/main
+ ```
+
Preflight the completed body through the requested environment interface,
then run the manifest's full PR-body job:
```bash
export PR_BODY="$(cat /tmp/harness-anything-pr-body.md)"
node tools/check-pr-body.mjs --env PR_BODY
export PR_BASE_SHA="$(git merge-base origin/main HEAD)"
export PR_HEAD_SHA="$(git rev-parse HEAD)"
node tools/run-manifest-gates.mjs --workflow-job pr-body-lint
unset PR_BODY PR_BASE_SHA PR_HEAD_SHA
```
[`references/example-pr-body.md`](references/example-pr-body.md) is a completed
docs-only example that exercises every section. It is a fixture, not a template:
always copy the live repository template for a real PR.
- > 中文:task submit 冻结交付 cut 后,用 renderer 生成 PR body 的 Delivery Facts;不得
- > 手抄或重算 SHA、基线、文件清单和 production delta。PR body 按模板填写人写的节;治理声明与 `Dependency-Change:` 仅在
+ > 中文:所有 commit 完成后运行 production-delta 计算器(它只从 diff 实算,不读 PR
+ > 正文)。PR body 按模板填写所有未注释的节;治理声明与 `Dependency-Change:` 仅在
> 触发条件成立时必填。外部贡献者在 Summary 里引用公开 issue 号,不要放私有 ID;无
> 依赖文件变化时删除整条 `Dependency-Change:`。Verification 只记录直接通过、或由
> runner 明确打印并通过的命令,其余写明未运行与原因。不得把未发生的 CI、人工
> review 或测试写成已完成。
## Push and open the PR
This section is the external-contributor path: it uses the contributor's own
Git credentials. A different model exists for dispatched, task-bound workers in
a registered Harness workspace — they publish the branch through the daemon with
- `ha task push <task-id>`, open the PR with
- `gh pr create --head <task-id> --body-file /tmp/harness-anything-pr-body.md`, with direct-push
+ `ha task push <task-id>`, open the PR with `gh pr create --head <task-id>`, with direct-push
protection limiting any push to the task's own branch. Read hosted checks and
failure logs directly with the hosting platform CLI and your own platform
credentials. If your session runs as such a worker, use those publishing
commands instead of this section; see
[Task branch publishing](../../docs-release/operations-server-daemon.md#task-branch-publishing-and-direct-push-protection).
Push only the contribution branch to a remote where the contributor has write
access:
```bash
git push -u <write-remote> HEAD
```
With an authenticated GitHub CLI, open the PR against the canonical `main`:
```bash
gh auth status
gh pr create --repo FairladyZ625/harness-anything --base main --head <github-user>:<branch> --title "<PR title>" --body-file /tmp/harness-anything-pr-body.md
```
If the branch is in the canonical repository rather than a fork, use
`--head <branch>`. Save the PR URL. Update the body rather than replacing it
with a shorter hand-written summary when later commits change scope or delta.
## Review and merge
Watch the protected checks and read the actual failure output:
```bash
gh pr view <pr-number> --repo FairladyZ625/harness-anything --json mergeable,mergeStateStatus
gh pr checks <pr-number> --repo FairladyZ625/harness-anything --watch
gh pr view <pr-number> --repo FairladyZ625/harness-anything --comments
```
Resolve a `DIRTY`/`CONFLICTING` merge state before waiting for checks: GitHub
does not run pull_request workflows for a conflicting PR, so no checks is not
evidence of a pending run.
Triage every concrete reviewer or bot finding. Before merge, each P0/P1/P2
finding must be fixed, explained as a false positive, deferred with an owner and
reason, or left explicitly blocking. For a fix, edit the same worktree, rerun
the smallest proving test and affected manifest jobs, make another prefixed
commit, push normally, and update the PR body. Never
force-push to escape a failed check.
External contributors and their agents stop after the PR is green, current,
conflict-free, and fully reviewed. A maintainer performs the repository's normal
merge-commit path; only that maintainer may run:
```bash
gh pr merge <pr-number> --repo FairladyZ625/harness-anything --merge --delete-branch
```
Do not squash, rebase-merge, direct-push, or use an admin bypass. The
contribution is complete when GitHub reports the PR merged or closed with a
clear reason.
> 中文:逐条处理 CI、human review 和 bot comment;P0/P1/P2 必须完成 triage。
> 外部贡献者或 agent 在 PR 全绿、无冲突、review 完成后停下,由 maintainer 用普通
> merge commit 合入。不得 squash、rebase merge、直推或 admin bypass。
## Agent contributor notes
An agent follows the same path and evidence standard as a human. It must keep
the declared scope visible, preserve unrelated work, show exact commands and
results, and leave external actions such as pushing or opening a PR within the
user's granted authority. It must not report human review, Dashboard
confirmation, release readiness, or merge approval on anyone else's behalf.
Before handoff, report:
- what changed and what stayed out of scope;
- exact tests and manifest jobs run, with pass/fail results;
- commands not run and the scoped reason;
- - the frozen submission facts and PR-body preflight result;
+ - the production delta and PR-body preflight result;
- open findings, residual risk, and the files needing human attention; and
- that merge remains maintainer-owned.
> 中文:agent 必须保留无关改动、如实报告命令结果,且不能替人声称人工确认、发布
> 就绪或合入批准。handoff 要写清改动、验证、未跑项、风险和 maintainer 合入边界。