From 5602ee552e1e4796764c49ec44d66d7893dfe4fc Mon Sep 17 00:00:00 2001 From: nick Date: Fri, 16 Oct 2026 18:28:59 +0800 Subject: [PATCH 1/2] ci(merge-queue): validate queued main candidates --- .github/workflows/ci.yml | 2 ++ tests/ci/policy.test.mjs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f6d1ae93..e3c65f2b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,8 @@ on: branches: [main] pull_request: branches: [main] + merge_group: + types: [checks_requested] workflow_dispatch: permissions: diff --git a/tests/ci/policy.test.mjs b/tests/ci/policy.test.mjs index 3d341aca..64cfb85d 100644 --- a/tests/ci/policy.test.mjs +++ b/tests/ci/policy.test.mjs @@ -174,6 +174,37 @@ function results(plan) { }; } +test('merge queue candidates run full checks even when their changes are documentation-only', t => { + const repo = repository(t); + repo.write('docs/site/package.json', JSON.stringify({ scripts: { check: 'node check.mjs' } })); + repo.write('docs/site/package-lock.json', '{}'); + const base = repo.commit(); + repo.write('docs/guide.md', '# Queued documentation change\n'); + const head = repo.commit(); + const event = resolve(repo.root, 'event.json'); + writeFileSync(event, JSON.stringify({ action: 'checks_requested', merge_group: { base_sha: base, head_sha: head } })); + const script = fileURLToPath(new URL('../../.github/scripts/ci-policy.mjs', import.meta.url)); + const env = { ...process.env, GITHUB_EVENT_NAME: 'merge_group', GITHUB_EVENT_PATH: event, + GITHUB_OUTPUT: resolve(repo.root, 'outputs'), GITHUB_STEP_SUMMARY: resolve(repo.root, 'summary') }; + delete env.GITHUB_TOKEN; + delete env.GH_TOKEN; + const plan = JSON.parse(execFileSync(process.execPath, [script, 'classify'], { cwd: repo.root, env, encoding: 'utf8' })); + assert.equal(plan.full_cpp, true); + assert.equal(plan.docs_check, true); + assert.equal(plan.files_known, false); + assert.equal(plan.reason, 'full-event'); + const valid = results(plan); + execFileSync(process.execPath, [script, 'gate'], { cwd: repo.root, + env: { ...env, CI_NEEDS_JSON: JSON.stringify(valid) }, stdio: ['ignore', 'pipe', 'pipe'] }); + for (const job of ['network', 'applications', 'database', 'documentation']) { + for (const result of ['skipped', 'failure', 'cancelled']) { + const invalid = structuredClone(valid); + invalid[job].result = result; + assert.throws(() => validateGate(invalid), `${job}/${result}`); + } + } +}); + test('the required gate accepts only the exact full or explicitly lightweight job plan', () => { for (const plan of [decision(['README.md']), decision(['docs/guide.md']), decision(['src/main.cpp']), decision(['src/main.cpp'], { site: { present: false, available: false } }), From 3a7fb06bec182c7a7359c5be9aaea0fc2d8a4a98 Mon Sep 17 00:00:00 2001 From: nick Date: Fri, 16 Oct 2026 18:36:23 +0800 Subject: [PATCH 2/2] docs(contributing): align delivery conventions with merge queue --- AGENTS.md | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..bb82e233 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,92 @@ +# Contributor and agent instructions + +These rules apply to this repository. Preserve unrelated work and use an isolated +branch or worktree when the existing checkout contains uncommitted changes. + +## Commits and pull requests + +- Write all new commit subjects and PR titles in English using Conventional + Commits: `type(scope): description`. Use a short, lowercase scope and an + imperative description of the resulting change. +- Types: `feat`, `fix`, `perf`, `refactor`, `docs`, `test`, `build`, `ci`, `style`, + `chore` and `revert`. Choose the type that describes the actual change; use + `style` only for formatting changes without behavior changes. +- Examples: `feat(config): support TOML application manifests`, + `fix(logging): preserve the configured log directory`, + `ci(cache): restore vcpkg package archives`. +- Name new topic branches `type/short-kebab-case`, matching the change, for example + `feat/database-coroutines`, `fix/windows-includes` or `docs/readme-maintainers`. + Do not use the `codex/` prefix or generic `xxx-branch` names. Existing published + branches do not need renaming solely to adopt this rule. Use lowercase names + for new GitHub repositories. +- Mark incompatible public changes with `!` and explain them in a + `BREAKING CHANGE:` footer. Describe migration steps in the PR and release notes. +- Keep each PR focused on one functional module or related change. Publish + independently reviewable work instead of accumulating unrelated modifications. +- All changes to `main` go through a PR. Do not push directly, force-push or delete + `main`, bypass branch protection, or rewrite already merged history. +- Use squash only after every required CI check passes and review conversations + are resolved. Outside the merge queue, synchronize the PR head with `main` + before acceptance. With the merge queue enabled, validate the queue candidate + containing the latest `main` and preceding queued changes; a green PR head alone + does not validate that combination. Add eligible PRs to the queue promptly. + Another maintainer's approval is not currently mandatory. Merge eligible PRs + without asking for confirmation again. +- Explicitly set the squash commit subject to the Conventional Commit PR title. + Replace GitHub's generated commit-list body with a concise change description; + do not copy intermediate commit subjects into release notes. + +## Verification and delivery + +- Run the checks relevant to the change before publishing. Report the exact + tested revision, commands, results and material limitations. +- Investigate failed CI logs before changing code or retrying. Do not repeatedly + rerun an unexplained failure, weaken tests or protection, or extend timeouts to + hide a defect. +- Pending, skipped, cancelled and successful checks are distinct states. A + cancelled run is not validation. If a run is cancelled for scheduling, record + the reason and resume its acceptance checks; do not leave it indefinitely red. +- Use the repository's change-scope policy: documentation changes run the relevant + documentation/link checks; code, build, dependencies and CI changes run the + full configured matrix. Never fabricate a passing required result. +- Include what changed, why, validation and remaining limits in PR descriptions. + Verify the merge result before saying that a PR has merged. + +## C++ and repository style + +- Use C++20 and consistent `snake_case` names, including types, functions and + members (`ark::plugin_manager`, `find_module()`, `module_name_`). Do not manually + edit generated protobuf output; change the schema or generation source. +- Follow `.clang-format` and the repository formatting scripts with clang-format + 18. Keep function opening braces on the declaration line, expand short function + bodies, and use braces for control statements. +- Group includes as system, third-party, then project headers. Keep required + platform-header dependencies in a valid order. Separate include blocks, + namespaces and adjacent definitions with the prescribed blank lines. +- Run `CLANG_FORMAT=/path/to/clang-format bash scripts/format.sh --check`. +- CI policy tests: `node --test tests/ci/*.test.mjs`. Nimbus documentation: + `npm ci --prefix docs/site` followed by `npm run check --prefix docs/site`. +- Keep official plugins in the ark repository and application business plugins + in application repositories. The approved layout has one public header root, + `include/ark/`, with implementation under `src/core/` and + `src/plugins//`; retain independent plugin targets and optional builds. + Verify migration status against accepted source before describing new paths + as available. Do not expand the paused hot-update design without discussing + its lifecycle and compatibility boundaries. + +## Documentation and releases + +- Keep English and Chinese documentation aligned. Keep the README concise and + place detailed usage, architecture and validation material under `docs/`. +- Write release notes for users: summarize core capabilities and group relevant + changes under Features, Improvements, Fixes and Upgrade notes. Omit empty + sections and combine implementation details into their user-visible effect. +- Do not publish a commit-by-commit diary, file list, formatting list or test + assertion inventory. Link detailed validation and performance reports instead. + Retain compatibility changes, security requirements and known limitations. +- Only describe changes contained in the release tag. Verify the release commit, + assets and checks before publishing; never move an existing release tag to + make unreleased work appear included. +- Keep raw measurements and build logs outside the source repository. Published + performance claims must identify the machine, workload, units and tested + revision; local tests do not establish production PCU capacity.