Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
5911421
docs: update handoff.md for completed v0.2.1 release
SHcommit Aug 31, 2026
121a217
ci: add PR title linter and update PR template for Conventional Commits
SHcommit Sep 1, 2026
d9a415a
docs: update changelog.md and handoff.md per AGENTS.md rules
SHcommit Sep 1, 2026
34bcd9a
feat(adapters): enhance Antigravity CLI plugin manifest and version sync
SHcommit Aug 31, 2026
cd9f997
feat(ci): add untracked manifest discovery, pre-commit config, and la…
SHcommit Sep 1, 2026
bc74d02
feat(ci): add .githooks/pre-push to prevent direct pushes to develop/…
SHcommit Sep 1, 2026
21d5bc7
docs: record .githooks/pre-push in changelog and handoff
SHcommit Sep 1, 2026
b9a0050
chore(version): sync adapters/antigravity/plugin.json version to 0.2.1
SHcommit Sep 1, 2026
437fc9e
docs: add architecture audit report and scope the Critical hardening …
SHcommit Sep 1, 2026
fc46830
feat: add atomic write and directory lock primitives
SHcommit Sep 1, 2026
49ede49
fix: make ADR creation race-free under concurrent invocation
SHcommit Sep 1, 2026
68bbd98
fix: make exception creation race-free under concurrent invocation
SHcommit Sep 1, 2026
cec7215
fix: make SUPERSEDE writes atomic and lock-protected
SHcommit Sep 1, 2026
c0ff907
fix: add ReDoS timeout guard to CHECK's author-supplied regex patterns
SHcommit Sep 1, 2026
7afdcd5
fix: escape ADR titles in generated README to prevent link injection
SHcommit Sep 1, 2026
11c8f4b
feat: add structured stderr logging with correlation IDs
SHcommit Sep 1, 2026
f0cbc86
docs: close out Critical hardening backlog items
SHcommit Sep 1, 2026
114bcaa
fix(ci): resolve Windows CP1252 UnicodeEncodeError in verify_examples…
SHcommit Sep 1, 2026
c1bdc4f
Merge pull request #6 from SHcommit/feature/agy-plugin-implements-2
SHcommit Sep 1, 2026
f92c8f5
fix: reject a --dir/--root that escapes the repository root
SHcommit Sep 1, 2026
52bd761
ci: measure and gate branch coverage at 85%
SHcommit Sep 1, 2026
305c836
feat: add typed result contracts and a mypy --strict CI gate
SHcommit Sep 1, 2026
46dd863
feat: add --diagnostic flag for per-invocation timing
SHcommit Sep 1, 2026
9708bb2
test: prove atomic_write_text survives a mid-write SIGKILL
SHcommit Sep 1, 2026
cff3d5e
feat: extract a shared adapter-manifest validator
SHcommit Sep 1, 2026
9a974b7
docs: close out High-priority hardening backlog items
SHcommit Sep 1, 2026
60fbb7e
merge: resolve merge conflicts in changelog.md and handoff.md
SHcommit Sep 1, 2026
47086c6
Merge pull request #7 from SHcommit/feature/add-githooks
SHcommit Sep 1, 2026
41998a2
feat: add a common domain-error base class and fix unhandled path-esc…
SHcommit Sep 1, 2026
e3d592b
test: detect drift between JSON Schema docs and runtime validators
SHcommit Sep 1, 2026
2933575
feat: extend output contract coverage to CHECK's result shape
SHcommit Sep 1, 2026
d7368f6
test: add a bulk-ADR performance sanity check
SHcommit Sep 1, 2026
c3ed01d
feat: add a TTY-only human summary line on stderr
SHcommit Sep 1, 2026
77ce206
docs: close out Medium-priority hardening backlog items
SHcommit Sep 1, 2026
1df6066
feat: extend output contract coverage to all 16 commands
SHcommit Sep 1, 2026
5859f99
docs: close out output contract coverage item
SHcommit Sep 1, 2026
8f7cd46
docs: populate cross-session handoff summary before switching sessions
SHcommit Sep 1, 2026
0a0db8a
Merge remote-tracking branch 'origin/develop' into feature/analyzing-…
SHcommit Sep 1, 2026
a7f2d3b
docs: add Low-priority tier to improvements.md from enterprise-adopti…
SHcommit Sep 1, 2026
c46b2e6
docs: add audit-report Low-risk items to improvements.md (corrects ea…
SHcommit Sep 1, 2026
0307a1c
feat: allow proposed->deprecated transition; document constraints: bl…
SHcommit Sep 1, 2026
9a44342
feat: lint constraints: blocks at CREATE/STATUS time, not just CHECK …
SHcommit Sep 1, 2026
466ffed
docs: close out 3 of 4 audit-report Low items, note parallel Codex work
SHcommit Sep 1, 2026
9a0de45
docs: design adoption metrics collector
SHcommit Sep 1, 2026
70e2dd2
feat: calculate adoption metrics from normalized events
SHcommit Sep 1, 2026
8ee84c0
feat: collect portable Git and GitHub metric evidence
SHcommit Sep 1, 2026
45b3472
feat: expose adoption metrics JSON collector
SHcommit Sep 1, 2026
26021a9
fix: reject nested-quantifier ReDoS patterns in constraints: blocks s…
SHcommit Sep 1, 2026
c651658
docs: record the Windows ReDoS mitigation, note parallel Codex work e…
SHcommit Sep 1, 2026
7f09a5d
fix: harden adoption metrics evidence handling
SHcommit Sep 1, 2026
e7829d1
docs: reconcile High-priority backlog against the merged agy/version-…
SHcommit Sep 1, 2026
7fb373e
fix: complete adoption metrics source contracts
SHcommit Sep 1, 2026
e00f48c
fix: validate current check snapshots
SHcommit Sep 1, 2026
276c6a0
docs: close out adoption metrics collector
SHcommit Sep 1, 2026
f814d64
docs: record final adoption metrics verification
SHcommit Sep 1, 2026
9223bfa
docs: mark adoption metrics complete
SHcommit Sep 1, 2026
18d4662
feat: add build provenance attestation to the release workflow
SHcommit Sep 1, 2026
cf6ed62
docs: close out supply-chain attestation and add worklog
SHcommit Sep 1, 2026
dd00e37
docs: add worklogs for the Critical/High hardening pass's core decisions
SHcommit Sep 1, 2026
c59d3db
docs: record this session's hardening decisions as ADR-0012..0016
SHcommit Sep 2, 2026
2d39348
chore: bump version to 0.3.0
SHcommit Sep 2, 2026
5e8307e
fix: make resolve_from_root's containment check filesystem-independent
SHcommit Sep 2, 2026
b30b0dd
Merge pull request #8 from SHcommit/feature/analyzing-adr-toolkit
SHcommit Sep 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "adr-toolkit",
"version": "0.2.1",
"version": "0.3.0",
"description": "Initialize, record, and check Architecture Decision Records by inspecting the repository and existing decisions before asking questions."
}
17 changes: 17 additions & 0 deletions .githooks/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash
# .githooks/pre-push
# Prevents direct git push to protected branches (develop, master)

protected_branches="^(develop|master)$"

while read local_ref local_oid remote_ref remote_oid; do
target_branch="${remote_ref#refs/heads/}"

if [[ "$target_branch" =~ $protected_branches ]]; then
echo "❌ [Direct Push Blocked] '$target_branch' 브랜치로 직접 push하는 것은 금지되어 있습니다."
echo " 반드시 feature/* 또는 fix/* 브랜치에서 PR(Pull Request)을 올려 병합하세요!"
exit 1
fi
done

exit 0
16 changes: 16 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
## PR Title Format

Please ensure your PR title follows Conventional Commits format:
`type(scope): description` (e.g. `feat(cli): add discover command`, `fix(check): fix unicode path matching`)

Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `chore`, `ci`

---

## Summary

-

## Examples Impact (Mandatory for `feat:` and `fix:`)

- [ ] `feat:` or `fix:` PR: I updated/added `examples/` and `examples/ko/` guides.
- [ ] I verified examples execution via `python3 scripts/verify_examples.py --check`.
- [ ] Non-feature change (`docs:`, `chore:`, `ci:`): No example changes needed.

## ADR Impact

- [ ] I checked whether this changes an accepted architectural decision.
Expand All @@ -13,6 +28,7 @@ Related ADRs:
## Verification

- [ ] `python3 -m pytest -q`
- [ ] `python3 scripts/verify_examples.py --check`
- [ ] `python3 scripts/sync_version.py --check`
- [ ] `python3 skills/adr-toolkit/scripts/adr.py validate --dir docs/decisions --json`
- [ ] `python3 skills/adr-toolkit/scripts/adr.py index --dir docs/decisions --json`
Expand Down
25 changes: 25 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,17 @@ jobs:
runs-on: ubuntu-latest
# softprops/action-gh-release needs write access to create the release;
# the default GITHUB_TOKEN is read-only for repos created since Feb 2023.
# attest-build-provenance needs id-token (to mint an OIDC token for
# Sigstore's keyless signing) and attestations: write (to publish the
# resulting attestation to the repo) -- no private key to manage or
# rotate; every install/consumption path here references the git repo
# or this packaged skill folder directly (docs/adr-toolkit-audit-report.md
# §2.2 2.2), so provenance tied to the exact commit is what actually
# matters, not a signed build of something nobody downloads separately.
permissions:
contents: write
id-token: write
attestations: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
Expand All @@ -32,7 +41,23 @@ jobs:
run: |
test "v$(cat skills/adr-toolkit/VERSION)" = "$GITHUB_REF_NAME" \
|| { echo "tag $GITHUB_REF_NAME != v$(cat skills/adr-toolkit/VERSION)"; exit 1; }
- name: Package the distributable skill
id: package
run: |
set -euo pipefail
VERSION="$(cat skills/adr-toolkit/VERSION)"
ARCHIVE="adr-toolkit-skill-v${VERSION}.tar.gz"
tar -czf "$ARCHIVE" -C skills adr-toolkit
sha256sum "$ARCHIVE" > "${ARCHIVE}.sha256"
echo "archive=$ARCHIVE" >> "$GITHUB_OUTPUT"
- name: Generate build provenance attestation
uses: actions/attest-build-provenance@v2
with:
subject-path: ${{ steps.package.outputs.archive }}
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
files: |
${{ steps.package.outputs.archive }}
${{ steps.package.outputs.archive }}.sha256
47 changes: 45 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,26 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: pip install pytest
run: pip install pytest pytest-cov
- name: Run tests
run: python -m pytest tests/unit tests/integration -v
run: python -m pytest tests/unit tests/integration -v --cov=skills/adr-toolkit/scripts --cov-branch --cov-report=term-missing --cov-fail-under=85

type-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install mypy
run: pip install mypy
- name: Type-check the fully-typed core modules
run: >-
mypy
skills/adr-toolkit/scripts/core/atomic_io.py
skills/adr-toolkit/scripts/core/telemetry.py
skills/adr-toolkit/scripts/core/contracts.py
--strict

version-drift:
runs-on: ubuntu-latest
Expand All @@ -43,6 +60,32 @@ jobs:
- name: Check manifest versions and descriptions are in sync
run: python scripts/sync_version.py --check

examples-drift:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Verify examples workflows execution and parity
run: python scripts/verify_examples.py --check

pr-title-check:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Validate PR Title Conventional Commits Format
run: |
TITLE="${{ github.event.pull_request.title }}"
echo "Checking PR Title: $TITLE"
REGEX="^(feat|fix|docs|style|refactor|perf|test|chore|ci)(\([a-z0-9-]+\))?!?: .+"
if [[ ! "$TITLE" =~ $REGEX ]]; then
echo "❌ PR Title does not match Conventional Commits format."
echo "Expected format: type(scope): description (e.g. feat(cli): add discover command)"
exit 1
fi
echo "✓ PR Title matches Conventional Commits format."

harness-parity:
# Installs the real Codex CLI and Gemini CLI and drives their own plugin
# commands against this repo, the same way a contributor would. Manifest
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,7 @@ adapters/antigravity/skills/adr-toolkit
# docs/superpowers/specs/ (the design docs) stay tracked; only plans/ is
# excluded. History from before this commit still has them if ever needed.
docs/superpowers/plans/

# Cross-process mutex file created by core/atomic_io.py's directory lock
# during create/exception/supersede -- a runtime artifact, not source.
.adr-toolkit.lock
15 changes: 15 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
repos:
- repo: local
hooks:
- id: sync-version-check
name: sync-version-check
entry: python3 scripts/sync_version.py --check
language: system
pass_filenames: false
always_run: true
- id: pytest-unit
name: pytest-unit
entry: python3 -m pytest tests/unit -q
language: system
pass_filenames: false
always_run: true
28 changes: 27 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Follow the repository policy in `AGENTS.md`.
- Release branches merge to `master` and back to `develop`.
- Tags named `v*` are created only from `master`.

## Local Checks
## Local Checks & Pre-Commit

Run the relevant checks before opening a pull request:

Expand All @@ -25,6 +25,19 @@ python3 skills/adr-toolkit/scripts/adr.py validate --dir docs/decisions --json
python3 skills/adr-toolkit/scripts/adr.py index --dir docs/decisions --json
```

You can also install the local pre-commit hook to run these checks automatically before committing:

```bash
pip install pre-commit
pre-commit install
```

### Plugin Adapters & Manifest Governance

If you add or modify a harness adapter (e.g. under `adapters/` or `.claude-plugin/`):
- Every `plugin.json` or `gemini-extension.json` must be registered in `MANIFEST_SPECS` and `DESCRIPTION_MANIFEST_SPECS` in `scripts/sync_version.py`.
- `python3 scripts/sync_version.py --check` will fail in CI if an untracked or out-of-sync manifest file is added.

For changes that may affect accepted architectural decisions, also run:

```bash
Expand All @@ -41,6 +54,19 @@ python3 skills/adr-toolkit/scripts/adr.py check --uncommitted --dir docs/decisio
- Accepted ADRs are append-only in spirit: use supersession for changed
decisions instead of rewriting history.

## `constraints:` Block Review

An ADR's `constraints:` block is enforced by `adr.py check` against every
future diff, so a change to one is a change to the repository's policy
surface, not just prose. Until CODEOWNERS-backed independent review is
active (see "Public Repository Hygiene" below), a PR that adds or edits a
`constraints:` block requires sign-off from someone with authority over
the affected `affected_paths`, in addition to normal review. This is a
process control, not a code sandbox -- see
`docs/adr-toolkit-audit-report.md` §2.2 2.1 for why isolation isn't the
right defense here (no third-party code executes; the block is
structured policy text).

## Public Repository Hygiene

Public repository branch/tag protection is expected to enforce PRs, required
Expand Down
29 changes: 29 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,35 @@ public issue. Include:
Do not include exploit details in a public issue until a fix or mitigation is
available.

## Verifying a Release

Every `v*` release is built by `.github/workflows/release.yml` from a
tagged commit, and the workflow publishes a [GitHub Artifact
Attestation](https://docs.github.com/en/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds)
for the packaged skill archive it attaches to the release
(`adr-toolkit-skill-vX.Y.Z.tar.gz`). This is a Sigstore-backed, keyless
signature -- no private key is held or rotated by this project -- proving
the archive was produced by this repository's own CI, from the exact
commit the release tag points to.

To verify a downloaded archive:

```bash
# Checksum: confirms the file wasn't corrupted/tampered with in transit
sha256sum -c adr-toolkit-skill-vX.Y.Z.tar.gz.sha256

# Provenance: confirms the archive was actually built by this repo's CI,
# not a look-alike release from a compromised account or a different repo
gh attestation verify adr-toolkit-skill-vX.Y.Z.tar.gz -R SHcommit/ADR-toolkit
```

Anyone consuming this repository directly (`git clone`, or an adapter's
`marketplace add`/`plugin add` pointing at the repo, which is how every
adapter installs this skill today) is verifying via Git/GitHub's own
commit and tag history rather than this archive -- the attestation is
primarily for the one path where a bare checkout doesn't happen: someone
who downloads the release archive off the GitHub Releases page directly.

## Scope

In scope:
Expand Down
3 changes: 2 additions & 1 deletion adapters/antigravity/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

Antigravity plugins are a `plugin.json` marker file plus optional sibling
directories (`skills/`, `agents/`, `rules/`), per
`antigravity.google/docs/cli/plugins/`. This manifest needs only `name`.
`antigravity.google/docs/cli/plugins/`. This manifest includes `name`,
`version`, `description`, and `$schema`.
**Manually verified against Antigravity's `agy` CLI 1.1.13** (`agy
--version`): validate, install, and discovery all work — see "Verification
status" below.
Expand Down
1 change: 1 addition & 0 deletions adapters/antigravity/plugin.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"$schema": "https://antigravity.google/schemas/v1/plugin.json",
"name": "adr-toolkit",
"version": "0.3.0",
"description": "Initialize, record, and check Architecture Decision Records by inspecting the repository and existing decisions before asking questions."
}
2 changes: 1 addition & 1 deletion adapters/gemini-cli/gemini-extension.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "adr-toolkit",
"version": "0.2.1",
"version": "0.3.0",
"description": "Initialize, record, and check Architecture Decision Records by inspecting the repository and existing decisions before asking questions."
}
Loading
Loading