diff --git a/docs/decisions/0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md b/docs/decisions/0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md
new file mode 100644
index 0000000..77791e8
--- /dev/null
+++ b/docs/decisions/0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md
@@ -0,0 +1,114 @@
+---
+id: ADR-0017
+title: Adopt source-controlled GitHub governance and CI supply-chain hardening
+status: accepted
+date: 2026-09-06
+locale: en
+decision_makers:
+ - YangSeungHyun
+related:
+ - ADR-0005
+ - ADR-0016
+affected_paths:
+ - .github/CODEOWNERS
+ - .github/dependabot.yml
+ - .github/labeler.yml
+ - .github/labels.yml
+ - .github/ISSUE_TEMPLATE/
+ - .github/workflows/test.yml
+ - .github/workflows/release.yml
+ - pyproject.toml
+ - scripts/export_dev_requirements.py
+ - tests/unit/test_github_governance.py
+ - SECURITY.md
+tags:
+ - github
+ - governance
+ - supply-chain
+ - ci
+ - security
+retrospective: false
+---
+
+# Adopt source-controlled GitHub governance and CI supply-chain hardening
+
+## Context and Problem Statement
+
+The repository became public on 2026-08-29 and shipped v1.0.0/v1.0.1, but the
+day-to-day contributor mechanics that keep a growing issue/PR queue navigable
+for a single maintainer were never built out. Labels were the GitHub defaults,
+issue templates were legacy Markdown, and there was no Dependabot, no
+CODEOWNERS, no path-based auto-labeler, no lint job, and no dependency/security
+scan. A prior audit also queried only the classic branch-protection endpoint
+and wrongly concluded the repo was unprotected; the repository ruleset API
+showed active branch/tag rulesets since 2026-09-02, but their required
+status-check names can drift whenever the CI matrix changes.
+
+## Decision Drivers
+
+* One maintainer and one repository: automation must pay for itself without
+ assuming a team that does not exist yet.
+* CI was already mature (multi-OS pytest matrix, coverage floor, scoped mypy
+ --strict, drift gates, pr-title-check, harness-parity) but had no lint and no
+ dependency/security scan.
+* harness-parity ran a remote `curl | bash` installer -- a supply-chain risk.
+* Every "not now" item must carry a written trigger, not a vague "later".
+
+## Considered Options
+
+* Keep hand-triage only -- does not scale past a handful of issues.
+* Adopt GitHub-native automation as code (labels, labeler, Dependabot, Issue
+ Forms) plus lint + dependency-audit CI gates, and sync the ruleset's required
+ checks to the CI matrix -- chosen.
+* Add heavy automation now (mandatory CODEOWNERS review, stale bot, org-wide
+ rulesets) -- deferred behind explicit preconditions.
+
+## Decision Outcome
+
+Chosen option: **source-controlled GitHub governance + CI supply-chain
+hardening**, because it lets issues/PRs self-organize and keeps required checks
+honest without over-automating a one-maintainer repository.
+
+* Path-based auto-labeler mapping changed-file globs to `area:*` labels, plus a
+ source-controlled label taxonomy (`.github/labels.yml`) synced live without
+ deleting unrelated labels.
+* Dependabot for pip and github-actions only, weekly, grouped, targeting
+ `develop`.
+* Structured Issue Forms for bug and feature reports, with `config.yml` routing
+ questions to Discussions and vulnerabilities to `SECURITY.md`.
+* Fast CI gates: ruff lint and `pip-audit --strict`; the Python floor moved from
+ 3.9 to 3.10.
+* Supply-chain hardening: the Antigravity `curl | bash` installer was replaced
+ with a versioned SHA-512-verified artifact; release Actions were pinned to
+ commit SHAs; the PR-title shell expression injection was removed.
+* Branch ruleset `22101891` required checks were synced to the new matrix
+ (Python 3.10 x3 + `lint` + `dependency-audit` added; Python 3.9 removed) and
+ re-verified through the effective-rules API.
+* A dormant CODEOWNERS was drafted but not wired to required review. Live
+ Discussions, Dependabot security updates/alerts, secret scanning + push
+ protection, and private vulnerability reporting were enabled.
+
+## Consequences
+
+* Good: new issues/PRs arrive pre-labeled; dependency bumps arrive as routine,
+ reviewable PRs; CI fails fast on lint and known vulnerabilities; protected
+ branches can no longer be silently blocked by a stale required-check name.
+* Bad: ruleset required checks are GitHub-side settings that cannot live fully
+ in code, so a future CI job rename still requires a manual ruleset sync; the
+ trigger for a read-only verification script is recorded in `improvements.md`.
+
+## Confirmation
+
+pytest (562 passed) plus branch coverage, ruff check, scoped mypy --strict,
+`sync_version.py --check`, and `verify_examples.py --check` all passed. The
+ruleset and effective-rules APIs confirm the new required checks are active for
+`develop`.
+
+## Revisit Triggers
+
+* A second qualified maintainer appears -> enable CODEOWNERS required review.
+* A second repository repeats the same operations -> org-level rulesets,
+ reusable workflows, audit export, and taxonomy.
+* A real abandoned-issue backlog accumulates -> stale bot.
+* CI check-name drift recurs -> ruleset-as-code or a read-only verification
+ script.
diff --git a/docs/decisions/README.md b/docs/decisions/README.md
index 02c424d..81c7f00 100644
--- a/docs/decisions/README.md
+++ b/docs/decisions/README.md
@@ -18,6 +18,7 @@
- [ADR-0014 — Typed result contracts and a scoped mypy --strict CI gate](0014-typed-result-contracts-and-a-scoped-mypy-strict-ci-gate.md)
- [ADR-0015 — Structured JSON stderr logging with correlation IDs for uncaught errors](0015-structured-json-stderr-logging-with-correlation-ids-for-uncaught-errors.md)
- [ADR-0016 — Sign release artifacts with GitHub Artifact Attestation instead of a managed signing key](0016-sign-release-artifacts-with-github-artifact-attestation-instead-of-a-managed-signing-key.md)
+- [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
### Superseded
- [ADR-0003 — Localize only index.py's generated strings, not agent-composed text](0003-localize-only-index-py-s-generated-strings-not-agent-composed-text.md)
@@ -38,6 +39,9 @@
- [ADR-0008 — Deterministic CHECK policy exceptions: schema-validated, annotate-only, never suppress](0008-check-exceptions-annotate-only.md)
- [ADR-0013 — Two-stage ReDoS defense for CHECK's author-supplied constraint regexes](0013-two-stage-redos-defense-for-check-s-author-supplied-constraint-regexes.md)
+### ci
+- [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
+
### cli
- [ADR-0009 — --json is a documented no-op; CLI output is always JSON](0009-json-flag-always-json-contract.md)
@@ -75,9 +79,13 @@
### git-flow
- [ADR-0005 — Adopt Git Flow with direct-tag release automation](0005-adopt-git-flow-with-direct-tag-release-automation.md)
+### github
+- [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
+
### governance
- [ADR-0008 — Deterministic CHECK policy exceptions: schema-validated, annotate-only, never suppress](0008-check-exceptions-annotate-only.md)
- [ADR-0011 — Expose ADR relationships as Mermaid and SVG navigation artifacts](0011-adr-relationship-graph-public-readiness.md)
+- [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
### graph
- [ADR-0011 — Expose ADR relationships as Mermaid and SVG navigation artifacts](0011-adr-relationship-graph-public-readiness.md)
@@ -115,9 +123,11 @@
### security
- [ADR-0013 — Two-stage ReDoS defense for CHECK's author-supplied constraint regexes](0013-two-stage-redos-defense-for-check-s-author-supplied-constraint-regexes.md)
- [ADR-0016 — Sign release artifacts with GitHub Artifact Attestation instead of a managed signing key](0016-sign-release-artifacts-with-github-artifact-attestation-instead-of-a-managed-signing-key.md)
+- [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
### supply-chain
- [ADR-0016 — Sign release artifacts with GitHub Artifact Attestation instead of a managed signing key](0016-sign-release-artifacts-with-github-artifact-attestation-instead-of-a-managed-signing-key.md)
+- [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
### typing
- [ADR-0014 — Typed result contracts and a scoped mypy --strict CI gate](0014-typed-result-contracts-and-a-scoped-mypy-strict-ci-gate.md)
@@ -148,17 +158,34 @@
### `.claude-plugin/plugin.json`
- [ADR-0004 — Adapter packaging: manifest-only directories, install-time symlinks, verified formats](0004-adapter-packaging-manifest-only-directories-install-time-symlinks-verified-formats.md)
+### `.github/CODEOWNERS`
+- [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
+
+### `.github/ISSUE_TEMPLATE/`
+- [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
+
### `.github/PULL_REQUEST_TEMPLATE.md`
- [ADR-0011 — Expose ADR relationships as Mermaid and SVG navigation artifacts](0011-adr-relationship-graph-public-readiness.md)
+### `.github/dependabot.yml`
+- [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
+
+### `.github/labeler.yml`
+- [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
+
+### `.github/labels.yml`
+- [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
+
### `.github/workflows/`
- [ADR-0005 — Adopt Git Flow with direct-tag release automation](0005-adopt-git-flow-with-direct-tag-release-automation.md)
### `.github/workflows/release.yml`
- [ADR-0016 — Sign release artifacts with GitHub Artifact Attestation instead of a managed signing key](0016-sign-release-artifacts-with-github-artifact-attestation-instead-of-a-managed-signing-key.md)
+- [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
### `.github/workflows/test.yml`
- [ADR-0014 — Typed result contracts and a scoped mypy --strict CI gate](0014-typed-result-contracts-and-a-scoped-mypy-strict-ci-gate.md)
+- [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
### `.gitignore`
- [ADR-0004 — Adapter packaging: manifest-only directories, install-time symlinks, verified formats](0004-adapter-packaging-manifest-only-directories-install-time-symlinks-verified-formats.md)
@@ -178,6 +205,7 @@
### `SECURITY.md`
- [ADR-0011 — Expose ADR relationships as Mermaid and SVG navigation artifacts](0011-adr-relationship-graph-public-readiness.md)
- [ADR-0016 — Sign release artifacts with GitHub Artifact Attestation instead of a managed signing key](0016-sign-release-artifacts-with-github-artifact-attestation-instead-of-a-managed-signing-key.md)
+- [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
### `adapters/`
- [ADR-0004 — Adapter packaging: manifest-only directories, install-time symlinks, verified formats](0004-adapter-packaging-manifest-only-directories-install-time-symlinks-verified-formats.md)
@@ -200,6 +228,12 @@
### `project-roadmap.md`
- [ADR-0011 — Expose ADR relationships as Mermaid and SVG navigation artifacts](0011-adr-relationship-graph-public-readiness.md)
+### `pyproject.toml`
+- [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
+
+### `scripts/export_dev_requirements.py`
+- [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
+
### `scripts/sync_version.py`
- [ADR-0005 — Adopt Git Flow with direct-tag release automation](0005-adopt-git-flow-with-direct-tag-release-automation.md)
@@ -334,6 +368,9 @@
### `tests/unit/test_contracts.py`
- [ADR-0014 — Typed result contracts and a scoped mypy --strict CI gate](0014-typed-result-contracts-and-a-scoped-mypy-strict-ci-gate.md)
+### `tests/unit/test_github_governance.py`
+- [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
+
### `tests/unit/test_graph_command.py`
- [ADR-0011 — Expose ADR relationships as Mermaid and SVG navigation artifacts](0011-adr-relationship-graph-public-readiness.md)
@@ -348,6 +385,7 @@
## Chronological (newest first)
+- 2026-09-06 — [ADR-0017 — Adopt source-controlled GitHub governance and CI supply-chain hardening](0017-adopt-source-controlled-github-governance-and-ci-supply-chain-hardening.md)
- 2026-09-01 — [ADR-0012 — Atomic writes and cross-platform directory locking for CREATE, EXCEPTION, and SUPERSEDE](0012-atomic-writes-and-cross-platform-directory-locking-for-create-exception-and-supersede.md)
- 2026-09-01 — [ADR-0013 — Two-stage ReDoS defense for CHECK's author-supplied constraint regexes](0013-two-stage-redos-defense-for-check-s-author-supplied-constraint-regexes.md)
- 2026-09-01 — [ADR-0014 — Typed result contracts and a scoped mypy --strict CI gate](0014-typed-result-contracts-and-a-scoped-mypy-strict-ci-gate.md)
@@ -386,6 +424,8 @@
- ADR-0015 "Structured JSON stderr logging with correlation IDs for uncaught errors" related to: ADR-0009 "--json is a documented no-op; CLI output is always JSON"
- ADR-0016 "Sign release artifacts with GitHub Artifact Attestation instead of a managed signing key" related to: ADR-0005 "Adopt Git Flow with direct-tag release automation"
- ADR-0016 "Sign release artifacts with GitHub Artifact Attestation instead of a managed signing key" related to: ADR-0011 "Expose ADR relationships as Mermaid and SVG navigation artifacts"
+- ADR-0017 "Adopt source-controlled GitHub governance and CI supply-chain hardening" related to: ADR-0005 "Adopt Git Flow with direct-tag release automation"
+- ADR-0017 "Adopt source-controlled GitHub governance and CI supply-chain hardening" related to: ADR-0016 "Sign release artifacts with GitHub Artifact Attestation instead of a managed signing key"
```mermaid
flowchart LR
@@ -405,6 +445,7 @@ flowchart LR
ADR_0014["ADR-0014 Typed result contracts and a scoped mypy --strict CI gate"]
ADR_0015["ADR-0015 Structured JSON stderr logging with correlation IDs for uncaught errors"]
ADR_0016["ADR-0016 Sign release artifacts with GitHub Artifact Attestation instead of a managed signing key"]
+ ADR_0017["ADR-0017 Adopt source-controlled GitHub governance and CI supply-chain hardening"]
ADR_0006 -.->|related| ADR_0003
ADR_0006 -->|supersedes| ADR_0003
ADR_0011 -.->|related| ADR_0001
@@ -419,4 +460,6 @@ flowchart LR
ADR_0015 -.->|related| ADR_0009
ADR_0016 -.->|related| ADR_0005
ADR_0016 -.->|related| ADR_0011
+ ADR_0017 -.->|related| ADR_0005
+ ADR_0017 -.->|related| ADR_0016
```
diff --git a/docs/decisions/relationships.mmd b/docs/decisions/relationships.mmd
index 91fe037..f13530d 100644
--- a/docs/decisions/relationships.mmd
+++ b/docs/decisions/relationships.mmd
@@ -15,6 +15,7 @@ flowchart LR
ADR_0014["ADR-0014 Typed result contracts and a scoped mypy --strict CI gate"]
ADR_0015["ADR-0015 Structured JSON stderr logging with correlation IDs for uncaught errors"]
ADR_0016["ADR-0016 Sign release artifacts with GitHub Artifact Attestation instead of a managed signing key"]
+ ADR_0017["ADR-0017 Adopt source-controlled GitHub governance and CI supply-chain hardening"]
ADR_0006 -.->|related| ADR_0003
ADR_0006 -->|supersedes| ADR_0003
ADR_0011 -.->|related| ADR_0001
@@ -29,3 +30,5 @@ flowchart LR
ADR_0015 -.->|related| ADR_0009
ADR_0016 -.->|related| ADR_0005
ADR_0016 -.->|related| ADR_0011
+ ADR_0017 -.->|related| ADR_0005
+ ADR_0017 -.->|related| ADR_0016
diff --git a/docs/decisions/relationships.svg b/docs/decisions/relationships.svg
index b267074..7571a90 100644
--- a/docs/decisions/relationships.svg
+++ b/docs/decisions/relationships.svg
@@ -1,4 +1,4 @@
-