7.0 KiB
Maintainer Automation Notes
This document keeps agent- and maintainer-specific workflow notes out of the repository root while preserving repo-local guidance for automation.
Read Order
README.mdCONTRIBUTING.mddocs/architecture.md- This document
Project Snapshot
dwsis a Go-based DingTalk Workspace CLI and MCP runtime bridge.- Product commands are loaded dynamically via
internal/pluginfrom bundled descriptors. - Command handlers live in
internal/helpers; runtime execution flows throughinternal/executorandinternal/transport.
Repository Map
cmd: public CLI entrypointinternal/app: root command wiring, static utility commands, plugin loadinginternal/helpers: product command handlers (dev, chat, calendar, contact, etc.)internal/plugin: plugin-based dynamic command loaderinternal/cli: catalog types and static endpoint loaderinternal/executor: invocation dispatch and result handlinginternal/transport: MCP HTTP client and request signinginternal/auth: login, token management, agent-code detectioninternal/audit: user operation audit loginternal/errors: structured error model with categories and hintsinternal/keychain: OS keychain integration for credential storageinternal/security: endpoint allowlist and domain trustinternal/pat: PAT (Personal Access Token) authorization flowdocs/: public architecture and reference docsscripts/: build, test, lint, packaging, and policy checkstest/: CLI, integration, contract, unit, and skill E2E test suites
Task Routing
- Add or fix a command path: start from
internal/helpers(handler implementations) orinternal/app(command tree wiring) - Protocol or transport issues: inspect
internal/transport - Auth or login issues: inspect
internal/auth,internal/pat,internal/keychain - Error message or category issues: inspect
internal/errors - Audit log issues: inspect
internal/audit - Plugin loading or command surface: inspect
internal/plugin - Failure or degraded mode: inspect
internal/errors,internal/recovery
Policy Checks
When command surface or plugin descriptors change, run:
./scripts/policy/check-command-surface.sh --strict./scripts/policy/check-open-source-assets.sh
Common Commands
make build
make test
make lint
./scripts/dev/ci-local.sh
git diff --check
Homebrew Formula PR Automation
Official tag releases require the repository Actions secret
HOMEBREW_PR_TOKEN. Prefer a fine-grained personal access token owned by a
maintainer or release-bot account, limited to this repository with
Contents: write and Pull requests: write. If organization policy prevents
that account from targeting the repository, use a dedicated classic token with
only the public_repo scope. Do not reuse a broad developer token.
Store the dedicated token as the HOMEBREW_PR_TOKEN repository Actions secret
and rotate it before its configured expiration. Replace it immediately if it is
exposed, its owner loses repository access, or the release-bot ownership
changes. The Release workflow uses this
dedicated token only to push an automation/homebrew-* branch and open the
stable or beta Formula PR. It does not push Formula changes directly to main.
The default-branch governance preflight and every tag contract authenticate the
token before publication, reject over-scoped classic tokens, confirm its
identity, and run a controlled write canary. The canary pushes a unique
automation/homebrew-token-canary-* branch with a [skip ci] commit, creates a
draft PR, closes it, and deletes the branch with the same token. This proves both
Contents and Pull requests write access before publication without merging
anything. The gate also rejects reuse of RELEASE_GOVERNANCE_TOKEN.
No maintainer environment variable is required when creating a tag. Using the
built-in GITHUB_TOKEN is insufficient because organization policy prevents
Actions from creating pull requests, and its generated PR events may require
separate workflow approval.
Release Governance and Recovery
Store RELEASE_GOVERNANCE_TOKEN as a dedicated Actions secret with only
repository Administration: read. The immutable-releases REST endpoint is an
administration setting and cannot be read by the workflow's built-in
GITHUB_TOKEN. Both the default-branch governance preflight and the tag
contract use this same credential so a missing or expired identity is detected
before an irreversible tag is created.
Create a protected release-recovery environment limited to protected
branches, with a required reviewer, self-review disabled, and administrator
bypass disabled. The workflow reads the environment through the GitHub API and
fails closed unless the required-reviewer, prevent-self-review, and protected-
branch rules are present.
Recovery is restricted to an existing annotated tag whose exact tag object,
commit, and failed tag-push run all match; it then reuses the normal release
jobs. Do not put publication secrets in temporary branches or create ad-hoc
recovery workflows.
Cloud-sealed releases mirror to OSS only when the repository variable
ENABLE_OSS_MIRROR is exactly true. Leave the variable unset while no Bucket
is provisioned; GitHub, npm, and Homebrew delivery can then complete without
running the OSS step. Once enabled, missing credentials, an invalid Bucket, or
an upload failure remains fail-closed. The cloud tag immutably records the
decision as OSS-Mirror: enabled|deferred; publication and withdrawal consume
that sealed value instead of the variable's later state. Deferred releases
cannot use repair_oss_version; enabling OSS applies to later release tags
until an audited immutable repair marker is implemented.
If an immutable GitHub Release and npm package were delivered but an enabled
downstream China mirror failed, dispatch the normal Release workflow from the
protected default branch with exactly one of repair_gitee_version or
repair_oss_version. Channel repair accepts a fully successful exact release,
or a failed exact-tag run only when its latest attempt completed the release
contract, build, Apple signature, immutable GitHub publication, and npm
delivery checks for the exact tagged commit. OSS repair additionally requires
the tag's sealed policy to be enabled. It then downloads and re-verifies the
immutable assets before invoking only the selected mirror. For a failed
release, an OSS repair requires the OSS step itself to be the recorded failure.
A Gitee repair accepts either a failed Gitee job or a Gitee job that was
skipped behind that OSS failure; the latter is an explicit Gitee backfill and
does not claim that OSS has been repaired. Gitee repair requires GITEE_TOKEN,
GITEE_USER, and GITEE_REPO; OSS repair requires OSS_ACCESS_KEY_ID,
OSS_ACCESS_KEY_SECRET, OSS_ENDPOINT, and OSS_BUCKET (with optional
OSS_PREFIX) as Actions secrets. Missing credentials fail the selected repair
closed.
Handoff Checklist
Before handoff, include:
- Changed files and why
- Verification commands run and outcomes
- Known risks or follow-up work