diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 447cf52..641b873 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,5 +1,5 @@ { "name": "adr-toolkit", - "version": "0.3.1", + "version": "0.3.2", "description": "Initialize, record, and check Architecture Decision Records by inspecting the repository and existing decisions before asking questions." } diff --git a/adapters/antigravity/plugin.json b/adapters/antigravity/plugin.json index 00d9b6d..702aa37 100644 --- a/adapters/antigravity/plugin.json +++ b/adapters/antigravity/plugin.json @@ -1,6 +1,6 @@ { "$schema": "https://antigravity.google/schemas/v1/plugin.json", "name": "adr-toolkit", - "version": "0.3.1", + "version": "0.3.2", "description": "Initialize, record, and check Architecture Decision Records by inspecting the repository and existing decisions before asking questions." } diff --git a/adapters/gemini-cli/gemini-extension.json b/adapters/gemini-cli/gemini-extension.json index 447cf52..641b873 100644 --- a/adapters/gemini-cli/gemini-extension.json +++ b/adapters/gemini-cli/gemini-extension.json @@ -1,5 +1,5 @@ { "name": "adr-toolkit", - "version": "0.3.1", + "version": "0.3.2", "description": "Initialize, record, and check Architecture Decision Records by inspecting the repository and existing decisions before asking questions." } diff --git a/changelog.md b/changelog.md index a05423a..2ccb47a 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,14 @@ Lightweight human-readable summary of meaningful repository changes. ## Unreleased +## v0.3.2 (2026-09-02) + +- Cleared completed work out of `improvements.md`'s `## Done` section + and `handoff.md`'s completed-task narrative, per both files' own + documented steady-state convention (resolved items live in this + changelog, git history, and `docs/decisions/` instead). No functional + changes. + ## v0.3.1 (2026-09-02) - Fixed the release workflow: GitHub's Artifact Attestation API rejects diff --git a/handoff.md b/handoff.md index 70dbfff..45f7223 100644 --- a/handoff.md +++ b/handoff.md @@ -1,285 +1,94 @@ # handoff.md -## Current task (2026-09-01) +## Current task -**The Critical, High-priority, and Medium-priority hardening passes are -all done.** Every findable item from `docs/adr-toolkit-audit-report.md` -that was in scope for this worktree is implemented, tested, and -committed on `feature/analyzing-adr-toolkit`. Branch stays as-is per -owner's explicit choice (not merged/PR'd yet). +None active. The audit-driven Critical/High/Medium hardening pass +(`docs/adr-toolkit-audit-report.md`) is complete and released as +**v0.3.1**. What shipped and why: `changelog.md` for the summary, +`docs/decisions/0012-*.md` through `0016-*.md` for the architectural +decisions (written via the ADR toolkit itself), and git history for +everything else. -**`origin/develop` was merged into this branch** after diverging -significantly: it now includes the `v0.2.1` release (examples redesign, -Korean docs suite, `scripts/verify_examples.py` verification pipeline), -the Antigravity (`agy`) plugin manifest enhancements, `.githooks/pre-push`, -and a Conventional-Commits PR title CI check -- all from other -worktrees/branches, per this repo's own scope split. The merge touched 3 -files with real conflicts, resolved as follows: -- `changelog.md`: their `v0.2.1` release cut moved the old "Unreleased" - bullets into a `## v0.2.1 (2026-08-31)` section and started a fresh - "Unreleased" for post-release work; this branch's 16 hardening bullets - were genuinely-still-unreleased, so they were merged into that same - fresh "Unreleased" section alongside their 7 new bullets. -- `tests/unit/test_antigravity_adapter.py`: both sides added a new test - function (this branch's shared-validator test, their symlink-layout - test) -- kept both. Their new test called `pytest.skip(...)` without - `import pytest`; added the import as part of resolving this, since - otherwise a symlink-unsupported environment would hit `NameError` - instead of skipping cleanly. -- `handoff.md` (this file): kept this branch's detailed history, folded - in a short note (this paragraph) about what merged in from develop. - `.github/workflows/test.yml` auto-merged cleanly (both sides' new CI - jobs coexist: `pytest`+coverage, `type-check`, `examples-drift`, - `pr-title-check`, `harness-parity`, `version-drift`). - -**Critical pass** (`docs/superpowers/plans/2026-09-01-critical-hardening.md`): -`fc46830` atomic write + lock primitives, `49ede49` create.py race fix, -`68bbd98` exception.py race fix, `cec7215` supersede.py atomic writes, -`c0ff907` ReDoS guard, `7afdcd5` README link-injection fix, `11c8f4b` -structured logging, `f0cbc86` docs closeout. - -**High-priority pass** (`docs/superpowers/plans/2026-09-01-high-priority-hardening.md`): -`f92c8f5` path escape guard (initial), `52bd761` coverage CI gate, -`305c836` mypy strict gate + contracts.py, `46dd863` `--diagnostic` flag, -`9708bb2` SIGKILL chaos test, `cff3d5e` adapter manifest validator, -`9a974b7` docs closeout. - -**Medium-priority pass** (`docs/superpowers/plans/2026-09-01-medium-priority-hardening.md`): -`41998a2` common `AdrToolkitError` base + fixed the path-escape gap the -High pass left behind (all 7 `resolve_from_root` call sites now catch -it), `e3d592b` schema-drift detection test (no `jsonschema` dependency -added -- see rationale in that commit), `2933575` extended -`contracts.py` to cover CHECK, `d7368f6` bulk-ADR performance sanity -check, `c3ed01d` TTY-only stderr summary line, `77ce206` docs closeout. - -**Follow-up** (owner asked to continue per `improvements.md`/`handoff.md` -after the Medium pass): `1df6066` extended `core/contracts.py` to cover -the remaining 14 commands (was 2/16, now 16/16) -- each shape read from -the actual `run()` return statements, not guessed, and spot-checked -against real error-path output for `status`/`supersede` too. - -**Low-priority follow-up** (3 of 4 audit-report Low items): -`0307a1c` allows `proposed -> deprecated` and documents `constraints:` -block review in `CONTRIBUTING.md`; `9a44342` adds `core/constraints.lint()` -and wires it into `create.py` (always) and `status.py` (only on -transition to `accepted`, since that's the status CHECK actually enforces -constraints against) so a typo surfaces at authoring time instead of only -at CHECK time -- `CreateResult`/`StatusResult` gained a `warnings` field -to match. The 4th item (Antigravity in `harness-parity`) stays open, -blocked on `agy` getting a public package registry. - -**Windows ReDoS gap closed** (`26021a9`, promoted from this file's own -Open Risks below, not a numbered backlog item): `core/constraints.py` -statically rejects nested-quantifier `pattern` values (`(a+)+`-shaped) at -parse time for `forbidden_import`/`dependency_forbidden` rules -- a -string-level check that works the same on every OS, unlike -`rules/conflict.py`'s SIGALRM-based runtime timeout (POSIX-only). Verified -against the real dogfooded `ADR-0011` constraints block (no false -positive) and that a rejected pattern never reaches `re.compile()`. -Heuristic, not a full ReDoS detector -- alternation-based shapes like -`(a|a)*` remain uncaught, noted in the code. - -**Backlog reconciliation** (docs-only, no commit yet as of writing this): -the owner pointed out that PR #6 (`feature/agy-plugin-implements-2`) and -PR #7 (`feature/add-githooks`) -- the "다른 워크트리" that the High -section's 2 items were deferred to -- are both already merged into -`origin/develop` and pulled into this branch. Re-checked both items -against the actual current code rather than assuming: the 8.4 -auto-version-direction review is genuinely done (no conflict found, -moved to `## Done`) and removed from Open; the supply-chain signing item -is genuinely still unimplemented (confirmed by reading `release.yml`) and -stays Open, just with the stale "다른 워크트리 확인" framing removed. -Also re-verified the Antigravity/harness-parity Low item is still -correctly blocked (agy still has no public registry, per -`adapters/antigravity/README.md`) -- not everything merged from that -worktree closes every item tied to it. - -**Supply-chain attestation completed** (`18d4662`, the item the -"Backlog reconciliation" note below left open): `.github/workflows/release.yml` -now packages `skills/adr-toolkit/` into a version-named tarball, SHA-256 -checksums it, and generates a Sigstore-backed GitHub Artifact Attestation -(`actions/attest-build-provenance@v2`, keyless/OIDC -- no private key to -manage or rotate) for it; both the tarball and checksum are attached to -the GitHub Release. Chose this over signing the git tag itself because -tags in this project are created locally by a human before the triggering -push (`AGENTS.md`'s documented release process), so CI has no way to -retroactively sign an already-pushed tag -- attestation instead ties -provenance to the exact commit the tag points to. `SECURITY.md` gained a -"Verifying a Release" section (`sha256sum -c` + `gh attestation verify`) -that also clarifies git-clone/adapter-install paths verify via Git/GitHub -history, not this archive. Full option analysis: -`docs/worklogs/2026-09-01-supply-chain-attestation.md`. Verified: YAML -syntax, full test suite green (541 passed, no regressions) -- the actual -OIDC attestation issuance/verification flow itself can only be confirmed -end-to-end on a real `v*` tag push, not locally. - -**Adoption metrics follow-up completed:** - -- [x] `9a0de45`..`f814d64` add the design, JSON-only - `scripts/adoption_metrics.py` collector, focused tests, review fixes, and - final verification records. - -The collector calculates all five metrics from `docs/enterprise-adoption.md` -§7 using ADR/exception data plus optional local Git, explicit JSONL event and -CHECK snapshot files, and GitHub review evidence. Incomplete evidence is -reported through coverage, availability, and warning fields rather than being -silently treated as complete data. - -All 3 plan files are gitignored by convention (`docs/superpowers/plans/`) -but still on disk in this worktree. - -`improvements.md` now has: an empty `### Critical` section, a `### High` -section containing only the 2 items explicitly deferred to another -worktree, and a `### Medium` section with exactly one item -- the -parsing-result cache, marked **declined with rationale** (see below). It -also has a **Low-priority tier with two sourced sub-groups**, added at -the owner's request: -- 4 items pulled from `docs/adr-toolkit-audit-report.md`'s own 🟢 Low-risk - findings (the ones that actually still need action -- most of the 8 - Low findings in that report were "no action needed" or already resolved - by this session's work or the `origin/develop` merge, e.g. its - Conventional-Commits PR title suggestion is now the merged-in - `pr-title-check` CI job). -- 4 items pulled from `docs/enterprise-adoption.md` §8 (a separate - governance/adoption-maturity report) -- see that file's notes below for - why most of those are precondition-gated rather than pure code tasks. - -(An earlier pass in this session mistakenly added only the -enterprise-adoption.md half when asked to pull Low items "from the -report" -- corrected once the ambiguity was pointed out.) - -**One Medium item was declined, not silently skipped:** the audit's -`functools.lru_cache` suggestion for parsing-result caching provides zero -real benefit for this CLI -- it's a fresh process per invocation (no -shared memory across separate `python adr.py X` calls, which was the -actual scenario the audit worried about), and no single command -internally re-parses the same file more than once. A cache that would -actually help (persistent, on-disk, mtime-keyed, shared across process -invocations) is a much bigger, staleness-risk-bearing feature -disproportionate to real ADR counts. Recorded in `improvements.md` with -this rationale. - -Notable things discovered mid-session, worth knowing if touching this -code again: - -- `create.py`/`exception.py`: naively wrapping everything in - `adr_directory_lock` made *dry runs* (and, for `exception.py`, - *schema-validation failures*) create the directory + lock file as a - side effect, breaking existing tests. Fixed by keeping preview/ - validation paths outside the lock. -- `supersede.py`: two existing tests monkeypatched `Path.write_text` - directly; retargeted to `supersede.atomic_io.atomic_write_text` once - writes moved through it. -- Repo-root `scripts/` and `skills/adr-toolkit/scripts/` share the import - name `scripts` -- anything new under repo-root `scripts/` needs - `importlib.util.spec_from_file_location` in its tests, like - `scripts/sync_version.py` and `scripts/adapter_sdk.py` both do. -- `PathEscapesRootError` was added in the High-priority pass but never - actually caught anywhere until the Medium pass noticed and fixed it -- - every *other* domain exception in this codebase is caught explicitly at - its call site, so an uncaught one was an inconsistency worth closing. -- Measured, not assumed: branch+statement coverage was 93.32% before the - 85% CI gate; `mypy --strict` had exactly 3 real errors on the 2 - pre-existing typed modules; a bare `dict` field in a TypedDict fails - `mypy --strict`'s `type-arg` check -- use `Dict[str, Any]`. - -## Scope for this worktree +## Scope - Domains 1 (core/plugin architecture) and 5 (governance/FSM) from the - audit report -- still out of scope, already scored well. -- **The Antigravity (`agy`) adapter and automatic-version-sync worktree - no longer exists as a separate concern** -- its work merged via GitHub - PR #6/#7 into `origin/develop`, which this branch pulled in (`0a0db8a`). - Re-verified against the actual merged code (not assumed): confirmed - `scripts/sync_version.py`/`release.yml` still do manual-only version - bumps (no conflict with the audit's recommendation -- that review item - is now closed, see `improvements.md`'s `## Done`); the supply-chain - checksum/signing gap this note originally flagged is also closed now - (`18d4662`, GitHub Artifact Attestation -- see `## Done` above). -- README prose (root README.md, `adapters/*/README.md` content) -- - still another worktree's; every fix across all passes that touched - adapter or generator code was a code fix, not README prose. -- The adoption-metrics collector is complete; future changes should preserve - its provider-neutral evidence contracts and JSON-only stdout behavior. + audit report are out of scope — already scored well. +- README prose (root `README.md`, `adapters/*/README.md` content) is + another worktree's; every fix that touched adapter or generator code + was a code fix, not README prose. +- `scripts/adoption_metrics.py` is complete; future changes should + preserve its provider-neutral evidence contracts and JSON-only stdout + behavior. ## Next step (for a new session picking this up cold) -**`improvements.md`'s `### High` section is now empty.** The last item -(supply-chain attestation) landed in `18d4662`. Everything left in -`## Open` is either precondition-gated on a real-world fact this -worktree can't change, or belongs to the parallel Codex session (already -done). Concretely: - -1. `improvements.md`'s `### Medium` and `### High` are both empty -- - nothing there to pick up. -2. `improvements.md`'s `### Low` → audit-report sub-group has exactly 1 - item left (Antigravity in `harness-parity`), re-verified against - `adapters/antigravity/README.md` and still blocked on an external fact - (agy has no public package registry) -- don't start it. -3. `improvements.md`'s `### Low` → enterprise-adoption.md sub-group has - 3 precondition-gated items (repository going public, 2+ maintainers, - 2+ repositories) -- **not pure code tasks**. -4. If the user says "continue" / "다음 작업 진행해줘" without naming a - task: there is no ready-to-start backlog item left -- say so and ask - what's next (a new audit finding, a precondition that's now met, or - finishing the branch) rather than inventing scope. -5. If the user wants to finish this branch (merge to `develop` / open a - PR): that decision was deferred every time it came up this session - (owner chose "keep as-is" each time) -- ask again fresh, don't assume - the answer carried forward. This branch already includes the merged - `origin/develop` history, so a future merge/PR back to `develop` - should be a clean fast-forward-friendly merge. With the backlog now - empty of startable items, this is a reasonable point to raise it. -6. If the user references a new audit finding or a fresh problem: that's - genuinely new work -- use the same pattern this session established - (writing-plans -> executing-plans, TDD, one commit per task, verify - real test/mypy output before each commit) rather than skipping - straight to edits. - -Every scope decision across all passes (Critical-then-High-then-Medium -ordering, domain 1/5 exclusion, the other-worktree exclusions, the -parsing-cache decline) was the owner's explicit call or a judgment call -made and explained in-session, not something derivable from the audit -report alone -- see `improvements.md`'s `## Done` for the full rationale -on each. +There is no ready-to-start backlog item in `improvements.md`. Concretely: + +1. `improvements.md`'s `### Low` → audit-report sub-group has exactly 1 + item left (Antigravity in `harness-parity`), blocked on `agy` having + no public package registry — don't start it without re-verifying that + fact changed. Its enterprise-adoption.md sub-group has 3 + precondition-gated items (repository going public, 2+ maintainers, + 2+ repositories) — **not pure code tasks**. +2. A GitHub Wiki was considered and explicitly declined for now — this + project's docs-as-ADRs model (versioned, reviewed, tied to releases) + already covers the need; a wiki would fragment that. Revisit only + once the repo is public and community-contributed FAQ/tutorial + content that doesn't fit README/examples actually starts + accumulating. +3. If the user says "continue" without naming a task: say there is no + ready-to-start backlog item and ask what's next rather than + inventing scope. +4. If the user references a new audit finding or a fresh problem: use + the pattern this project uses for hardening work — writing-plans -> + executing-plans, TDD, one commit per task, verify real test/mypy + output before each commit — rather than skipping straight to edits. +5. This repository enforces a local `.githooks/pre-push` hook that + blocks direct pushes to `develop`/`master` (no GitHub branch + protection is configured — the repo is private, which is a GitHub + Pro-only feature — so the hook is the *only* enforcement). Any merge + into either branch needs a short-lived branch + `gh pr create` + + `gh pr merge`, not a direct push. A release follows Git Flow: tag + from `master` only, after a `release/*` (or `hotfix/*` for a + post-release bug) branch merges in via PR, then merge `master` back + into `develop`. +6. GitHub Artifact Attestation (`.github/workflows/release.yml`) is + skipped while this repository is private (GitHub rejects it for a + user-owned private repo) and starts running automatically once the + repo goes public — no workflow change needed then. ## Verification -`python3 -m pytest tests/unit tests/integration -q` -> 541 passed after the -adoption-metrics collector and review fixes. `mypy --strict` over the three CI -target modules, examples verification, version-sync verification, collector -compilation, and `git diff --check` also pass. -CI now also runs `type-check` (`mypy --strict`), `examples-drift` (from -develop), and `pr-title-check` (from develop) jobs alongside the existing -`pytest` (now coverage-gated at 85%), `version-drift`, and -`harness-parity` jobs. +`python3 -m pytest tests/unit tests/integration -q` and +`python3 scripts/sync_version.py --check` should both pass before any +commit; `mypy --strict` covers the fully-typed core modules +(`atomic_io`, `telemetry`, `contracts`) via CI's `type-check` job. CI +also runs `examples-drift`, `pr-title-check`, `version-drift`, and +`harness-parity` (installs the real Codex/Gemini CLIs) alongside the +coverage-gated (85%) `pytest` job. ## Open risks -- ~~The ReDoS guard is POSIX-only...~~ **Mitigated (`26021a9`)**: the - runtime SIGALRM timeout is still POSIX-only, but a static - nested-quantifier check in `core/constraints.py` now rejects the most - common ReDoS shape at parse time on every platform, so Windows is no - longer completely unguarded. Not a full ReDoS detector -- alternation- - based patterns (`(a|a)*`-shaped) still rely on the POSIX-only runtime - guard and remain unmitigated on Windows. +- The ReDoS runtime timeout (`rules/conflict.py`) is POSIX-only; a + static nested-quantifier check in `core/constraints.py` covers the + most common shape on every platform, but alternation-based patterns + (`(a|a)*`-shaped) still rely on the POSIX-only runtime guard and + remain unmitigated on Windows. - `supersede.py`'s two-file update guarantees each individual file is never torn by a mid-write crash, but not that the *pair* stays - consistent if killed between the two writes -- true two-phase commit + consistent if killed between the two writes — true two-phase commit was explicitly scoped out. - Every successful `create`/`exception`/`supersede` call leaves a - `.adr-toolkit.lock` (0-byte dotfile) permanently inside - `docs/decisions/` and `docs/decisions/exceptions/` -- intentional (the + `.adr-toolkit.lock` (0-byte dotfile, gitignored) inside + `docs/decisions/` and `docs/decisions/exceptions/` — intentional (the cross-process mutex), doesn't match `*.md`/`*.json` globs. -- `core/contracts.py` now covers all 16 commands' result shapes, but +- `core/contracts.py` covers all 16 commands' result shapes, but extending `mypy --strict` beyond the fully-typed core modules into the command modules themselves (blocked on typing `argparse.Namespace` args) is still future work. -- (carried over from the audit, still true) CHECK deliberately cannot - prove prose, business rationale, or organizational claims. -- (carried over, still true) GitHub branch/tag protection is unavailable - on the current private plan; revisit once the repository goes public - after most audit findings are done and the version bumps to 1.0.0 (see - project memory `project_v1_public_release_plan`) -- this is also the - precondition blocking `improvements.md`'s new Low-priority item #1 - (`docs/enterprise-adoption.md`'s public-transition ruleset gate). +- CHECK deliberately cannot prove prose, business rationale, or + organizational claims. +- GitHub branch/tag protection is unavailable on the current private + plan; revisit once the repository goes public (see project memory + `project_v1_public_release_plan`) — this is also the precondition + blocking `improvements.md`'s public-transition ruleset item. diff --git a/improvements.md b/improvements.md index 97d43f0..7d2a10c 100644 --- a/improvements.md +++ b/improvements.md @@ -5,19 +5,14 @@ Concrete implementation backlog. Unscheduled product bets belong in ## Open -Backlog derived from `docs/adr-toolkit-audit-report.md`. Scope for this -worktree excludes domains 1 (core/plugin architecture) and 5 (governance/ -FSM) — already scored 72/80 and mostly "no action needed" in the audit. -The Antigravity-adapter and automatic-version-sync work that used to be -a separate worktree has since been merged via GitHub PR #6/#7 into -`origin/develop`, which this branch pulled in (`0a0db8a`) — "다른 -워크트리 확인" items were re-checked against that merged code and either -closed out or reworded below. README prose is still another worktree's. +Backlog derived from `docs/adr-toolkit-audit-report.md`. Scope excludes +domains 1 (core/plugin architecture) and 5 (governance/FSM) — already +scored 72/80 and mostly "no action needed" in the audit. README prose is +another worktree's. ### High -`### High`에 남은 항목 없음 — 마지막 항목(공급망 보안)은 아래 `## Done` -참고. +None open. ### Medium @@ -34,15 +29,13 @@ closed out or reworded below. README prose is still another worktree's. 두 개의 서로 다른 출처가 섞여 있어 각 항목에 출처를 명시했다. -**출처: `docs/adr-toolkit-audit-report.md`의 🟢 Low 리스크 항목 8개 중, -"추가 조치 불요"이거나 이미 해소된 것을 제외하고 실제로 안 한 것 4건 -중 3건 완료(`0307a1c`, `9a44342`). 남은 건 1건뿐:** +**출처: `docs/adr-toolkit-audit-report.md`의 🟢 Low 리스크 항목** — 남은 +건 1건뿐: - [ ] *(전제조건: Antigravity CLI가 공개 패키지 레지스트리 지원)* - **harness-parity CI에 Antigravity 편입** — agy 관련 작업(PR #6)은 - 이미 병합됐지만 `adapters/antigravity/README.md`를 재확인한 결과 여전히 - "Manually verified"뿐, agy 자체가 아직 공개 패키지 레지스트리를 - 지원하지 않음 — 전제조건 그대로 미충족. (감사 보고서 §2.1 1.2) + **harness-parity CI에 Antigravity 편입** — `adapters/antigravity/README.md` + 기준 여전히 "Manually verified"뿐, agy 자체가 아직 공개 패키지 레지스트리를 + 지원하지 않음 — 전제조건 미충족. (감사 보고서 §2.1 1.2) **출처: `docs/enterprise-adoption.md` §4/§6-9** — 코드/아키텍처 감사와는 별개의, 조직 도입·거버넌스 성숙도를 다루는 문서. 아래 항목 대부분은 @@ -50,102 +43,12 @@ closed out or reworded below. README prose is still another worktree's. 전환, 유지관리자 인원, 저장소 개수)에 막혀 있으니, 시작 전에 전제조건부터 확인할 것. -- [ ] *(전제조건: 저장소 public 전환)* **Public 전환 게이트 실제 적용** — PR template/`CONTRIBUTING.md`/`SECURITY.md`는 이미 존재함(v0.2.1에 포함, `origin/develop` 병합으로 확인). 남은 건 `master`/`develop`/`v*` 태그에 대한 실제 GitHub ruleset(PR 필수, required CI, conversation resolution, force-push/삭제 차단) 적용과 API로 실제 상태 재조회뿐 — 코드 작업이 아니라 저장소를 public 전환한 뒤 GitHub 설정/API에서 해야 하는 작업. `project_v1_public_release_plan` 메모리 참고(1.0.0 시점 public 전환 계획). (enterprise-adoption.md §4, §9) +- [ ] *(전제조건: 저장소 public 전환)* **Public 전환 게이트 실제 적용** — PR template/`CONTRIBUTING.md`/`SECURITY.md`는 이미 존재함. 남은 건 `master`/`develop`/`v*` 태그에 대한 실제 GitHub ruleset(PR 필수, required CI, conversation resolution, force-push/삭제 차단) 적용과 API로 실제 상태 재조회뿐 — 코드 작업이 아니라 저장소를 public 전환한 뒤 GitHub 설정/API에서 해야 하는 작업. `project_v1_public_release_plan` 메모리 참고(1.0.0 시점 public 전환 계획). (enterprise-adoption.md §4, §9) - [ ] *(전제조건: qualified maintainer 2명 이상)* **CODEOWNERS 독립 승인 활성화** — 현재 1인 운영 상태에서 필수 code-owner review를 켜면 운영을 막거나 형식적 self-review만 만든다고 보고서 자체가 명시적으로 경고함. 인원 조건 충족 전엔 시작하지 않음. (enterprise-adoption.md §4, §9 "지금 구현하지 않을 것") - [ ] *(전제조건: 저장소 2개 이상)* **조직 단위 ruleset/reusable workflow/audit export/taxonomy** — 여러 저장소가 같은 운영 문제를 반복할 때 설계 시작. 지금은 저장소가 1개뿐이라 시작 조건 미충족. (enterprise-adoption.md §6, §8 항목 5) ## Done Normally this section stays empty between sessions (resolved items live in -`changelog.md` + git history instead). Populated once here as a -cross-session handoff summary at the owner's explicit request — clear this -back out next time a session does routine cleanup, per the usual rule. - -All of it is on branch `feature/analyzing-adr-toolkit`, not merged/PR'd -into `develop` yet (owner's explicit choice: keep as-is). `origin/develop` -was merged **into** this branch (not the other way around) to pick up its -`v0.2.1` release, Antigravity plugin work, and CI additions — see -`handoff.md` for the 3-file conflict resolution. Full detail, code, and -rationale for every hardening item lives in -`docs/adr-toolkit-audit-report.md` and the 3 (gitignored) plan files under -`docs/superpowers/plans/2026-09-01-*`. - -**Critical** — atomic writes + directory locking (`core/atomic_io.py`, -wired into create/exception/supersede so concurrent invocations can't -duplicate ADR/exception IDs or corrupt files); ReDoS timeout guard on -CHECK's author-supplied regex patterns; Markdown link-injection escape in -the generated `docs/decisions/README.md`; structured stderr logging with -correlation IDs (`core/telemetry.py`). - -**High** — `--dir`/`--root` path-escape guard (`PathEscapesRootError`); -CI branch-coverage gate at 85% (measured baseline: 93.32%); `mypy --strict` -CI gate + `core/contracts.py` (typed result shapes); `adr.py --diagnostic` -timing flag; OS-level (fork+SIGKILL) proof that a mid-write crash never -tears an ADR file; shared adapter-manifest validator -(`scripts/adapter_sdk.py`) used by all 4 manifest-based harness adapters; -supply-chain build provenance attestation on the release pipeline -(`18d4662`) — `.github/workflows/release.yml` now packages -`skills/adr-toolkit/` into a version-named tarball, SHA-256 checksums it, -and generates a Sigstore-backed GitHub Artifact Attestation -(`actions/attest-build-provenance@v2`, keyless/OIDC) for it; `SECURITY.md` -gained a "Verifying a Release" section. This was the last item in -`### High`; see `docs/worklogs/2026-09-01-supply-chain-attestation.md` -for the full option analysis and rationale. - -**Medium** — common `AdrToolkitError` base class for all 6 domain -exceptions (also closed a gap: `PathEscapesRootError` was raised but never -actually caught at any of its 7 call sites until this pass); schema-drift -regression test between `schemas/*.json` and the runtime validators (no -`jsonschema` dependency added, by design); bulk-ADR (200 fixtures) -performance sanity check; TTY-only human summary line on stderr -(`ADR_TOOLKIT_NO_COLOR` to suppress); `core/contracts.py` extended from -2/16 to 16/16 commands. - -**Declined, not done** — parsing-result caching (`functools.lru_cache`): -this CLI is a fresh process per invocation, so an in-process cache can't -reduce the actual cross-invocation re-parsing the audit worried about, and -no single command re-parses a file more than once internally either. Left -as a Critical-domain note in `docs/adr-toolkit-audit-report.md`, not -reopened without a real usage signal that changes this analysis. - -**Low (audit-report-sourced, 3 of 4)** — `constraints:` block review -documented in `CONTRIBUTING.md`; `proposed → deprecated` lifecycle -transition added; CHECK's constraints-block lint moved earlier to -CREATE/STATUS time (`core/constraints.lint()`, new `warnings` field on -`CreateResult`/`StatusResult`) so a typo surfaces at authoring time -instead of only when CHECK later runs against it. The 4th item -(Antigravity in harness-parity CI) stays open, blocked on `agy` getting a -public package registry. - -- [x] **도입 지표(adoption metrics) 수집 스크립트** — - `scripts/adoption_metrics.py`가 `docs/enterprise-adoption.md` §7의 다섯 - 지표를 JSON으로 계산한다. ADR/exception 스냅샷, 로컬 Git, 명시적 JSONL, - CHECK 스냅샷, 선택적 GitHub 리뷰 근거를 지원하며 불완전한 근거는 - coverage/availability/warning으로 노출한다. (`9a0de45`..`f814d64`) - -**Windows ReDoS static complexity linter** (promoted from `handoff.md`'s -Open Risks, not originally a numbered backlog item) — `core/constraints.py` -now statically rejects a nested-quantifier `pattern` value (e.g. `(a+)+`) -at parse time for `forbidden_import`/`dependency_forbidden` rules, closing -the gap where `rules/conflict.py`'s runtime SIGALRM timeout guard is -POSIX-only and Windows had zero ReDoS protection. Heuristic, not a full -detector -- alternation-based ReDoS shapes remain uncaught. - -**8.4 자동 버전 산정 방향 재검토 — reviewed, closed, no code change.** -The Antigravity/version-sync worktree's work merged in via PR #6/#7 -(`origin/develop`, pulled into this branch at `0a0db8a`). Re-checked -`scripts/sync_version.py` and `.github/workflows/release.yml` against the -audit's original recommendation ("manual version bump, don't force -semantic-release-style automation") -- confirmed no conflict: versioning -is still manual (`VERSION` file + `sync_version.py --check`), no -auto-bump tooling was introduced. Removed from Open; the supply-chain -signing item stays open (verified not implemented) but no longer flagged -"다른 워크트리 확인" since that worktree's work is already merged. - -Test suite: 395 → 465 passing (this branch's own work), zero regressions; -469 after merging `origin/develop`; 479 after the Low-priority follow-up -work; 518 as of this note (includes a parallel Codex session's own -adoption-metrics commits landing in this same branch -- see `handoff.md`, -not itemized here since that work isn't this session's to describe). CI -gained a `type-check` job and an 85% coverage gate (this branch), plus -`examples-drift` and `pr-title-check` jobs (from `origin/develop`). +`changelog.md` + git history instead, and this session's own architectural +decisions in `docs/decisions/ADR-0012..0016`). diff --git a/skills/adr-toolkit/SKILL.md b/skills/adr-toolkit/SKILL.md index d781ea1..e27bb12 100644 --- a/skills/adr-toolkit/SKILL.md +++ b/skills/adr-toolkit/SKILL.md @@ -2,7 +2,7 @@ name: adr-toolkit description: Initialize, record, and check Architecture Decision Records by inspecting the repository and existing decisions before asking questions. user-invocable: true -version: 0.3.1 +version: 0.3.2 --- # ADR Toolkit diff --git a/skills/adr-toolkit/VERSION b/skills/adr-toolkit/VERSION index a2268e2..9fc80f9 100644 --- a/skills/adr-toolkit/VERSION +++ b/skills/adr-toolkit/VERSION @@ -1 +1 @@ -0.3.1 \ No newline at end of file +0.3.2 \ No newline at end of file