Drop the recovery package/commands and related Schema/skill teaching so agents stop being steered at a dead surface, while keeping mono↔multi content QA work. Co-authored-by: Cursor <cursoragent@cursor.com>
140 lines
6.7 KiB
Markdown
140 lines
6.7 KiB
Markdown
# 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
|
|
|
|
1. `README.md`
|
|
2. `CONTRIBUTING.md`
|
|
3. `docs/architecture.md`
|
|
4. This document
|
|
|
|
## Project Snapshot
|
|
|
|
- `dws` is a Go-based DingTalk Workspace CLI and MCP runtime bridge.
|
|
- Product commands are loaded dynamically via `internal/plugin` from bundled descriptors.
|
|
- Command handlers live in `internal/helpers`; runtime execution flows through `internal/executor` and `internal/transport`.
|
|
|
|
## Repository Map
|
|
|
|
- `cmd`: public CLI entrypoint
|
|
- `internal/app`: root command wiring, static utility commands, plugin loading
|
|
- `internal/helpers`: product command handlers (dev, chat, calendar, contact, etc.)
|
|
- `internal/plugin`: plugin-based dynamic command loader
|
|
- `internal/cli`: catalog types and static endpoint loader
|
|
- `internal/executor`: invocation dispatch and result handling
|
|
- `internal/transport`: MCP HTTP client and request signing
|
|
- `internal/auth`: login, token management, agent-code detection
|
|
- `internal/audit`: user operation audit log
|
|
- `internal/errors`: structured error model with categories and hints
|
|
- `internal/keychain`: OS keychain integration for credential storage
|
|
- `internal/security`: endpoint allowlist and domain trust
|
|
- `internal/pat`: PAT (Personal Access Token) authorization flow
|
|
- `docs/`: public architecture and reference docs
|
|
- `scripts/`: build, test, lint, packaging, and policy checks
|
|
- `test/`: CLI, integration, contract, unit, and skill E2E test suites
|
|
|
|
## Task Routing
|
|
|
|
- Add or fix a command path: start from `internal/helpers` (handler implementations) or `internal/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`
|
|
|
|
## 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
|
|
|
|
```bash
|
|
make build
|
|
make test
|
|
make lint
|
|
./scripts/dev/ci-local.sh
|
|
git diff --check
|
|
```
|
|
|
|
## Homebrew Formula Delivery
|
|
|
|
Official releases use the Release workflow's built-in `GITHUB_TOKEN` to update
|
|
exactly one tracked Formula after the immutable GitHub assets and their
|
|
checksums have passed verification. The publisher validates the rendered Ruby,
|
|
commits only the configured Formula path, never force-pushes `main`, and retries
|
|
from a fresh clone up to three times when `main` advances concurrently. Normal
|
|
stable and beta releases do not create a Formula PR or run a permission
|
|
canary. The workflow uses the existing repository-scoped
|
|
`HOMEBREW_PR_TOKEN` release identity because GitHub does not allow its built-in
|
|
Actions App to bypass this repository's rulesets. That identity is the sole
|
|
user bypass actor on the two default-branch rulesets. The workflow creates the
|
|
nine Code Admission checks for the Formula-only commit only after proving its
|
|
sole parent already has all nine successful checks and the committed Formula
|
|
exactly matches this release's verified bytes.
|
|
|
|
Keep `HOMEBREW_PR_TOKEN` repository-scoped with `Contents: write` and
|
|
`Pull requests: write` (the latter remains necessary for withdrawal rollback),
|
|
keep its owner as the designated ruleset bypass actor, and do not reuse
|
|
`RELEASE_GOVERNANCE_TOKEN`. The workflow and publisher provide the Formula-only
|
|
path restriction; GitHub rulesets do not infer that restriction from the token.
|
|
|
|
## 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.
|
|
|
|
Recovery is restricted to an existing annotated tag whose exact tag object,
|
|
commit, sealed metadata, original failed run/attempt, requester identity and
|
|
Release state all match; it then reuses the normal release jobs without a
|
|
second-person environment approval. A same-run “Re-run failed jobs” is even
|
|
lighter: the seal job may adopt an existing tag only when its complete
|
|
authority matches that run and its original attempt is not newer than the
|
|
current attempt. 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:
|
|
|
|
1. Changed files and why
|
|
2. Verification commands run and outcomes
|
|
3. Known risks or follow-up work
|