Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
29 changes: 29 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# .editorconfig — rendered by adopt-standard.sh (verbatim; no placeholders).
# Mirrors the standards repo's own root .editorconfig.
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 2

[*.{sh,bash,bats}]
indent_size = 2

[*.rego]
indent_size = 2

[*.py]
indent_size = 4

[*.md]
trim_trailing_whitespace = false # markdown hard line breaks

[Makefile]
indent_style = tab

[*.{ps1,psm1,bat,cmd}]
end_of_line = crlf
43 changes: 43 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# .gitattributes — rendered by adopt-standard.sh (verbatim; no placeholders).
# Mirrors the standards repo's own root .gitattributes.
#
# Normalize to LF in the repository for everything text. Working-copy line
# endings are pinned per type so MinGW/Git-Bash scripts (LF) and native
# Windows scripts (CRLF) both work. This overrides core.autocrlf.
* text=auto eol=lf

# Unix shell / POSIX tooling — MUST stay LF in the working copy
*.sh text eol=lf
*.bash text eol=lf
*.bats text eol=lf
*.rego text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.json text eol=lf
*.toml text eol=lf
*.md text eol=lf
*.env text eol=lf
Makefile text eol=lf
.sops.yaml text eol=lf

# Native Windows scripts — CRLF in the working copy
*.ps1 text eol=crlf
*.psm1 text eol=crlf
*.bat text eol=crlf
*.cmd text eol=crlf

# Encrypted secret files are text (diffable ciphertext), kept LF
*.enc.yaml text eol=lf
*.enc.json text eol=lf
*.sops.yaml text eol=lf
*.sops.json text eol=lf

# Binary — never touch
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.gz binary
*.zip binary
*.tar binary
52 changes: 52 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
name: Bug report
about: Report something that is broken or behaves incorrectly
title: "bug: <short summary>"
labels: [bug, triage]
assignees: []
---

<!--
Rendered into <repo>/.github/ISSUE_TEMPLATE/ by adopt-standard.sh.
SECURITY: do NOT paste secrets, private keys, tokens, or production hostnames.
If this is a security vulnerability, do NOT file a public issue — see SECURITY.md.
-->

## Summary

<!-- One sentence: what is wrong? -->

## Steps to reproduce

1.
2.
3.

## Expected behaviour

<!-- What you expected to happen. -->

## Actual behaviour

<!-- What actually happened. Include error output (redact any secrets). -->

```text

```

## Environment

- Repo version / commit:
- Adopted standard version (`.standards-version`):
- OS / runtime:
- CI or local:

## Impact

- [ ] Blocks work / production
- [ ] Workaround exists
- [ ] Cosmetic / minor

## Additional context

<!-- Links, screenshots (no secrets), related issues. -->
13 changes: 13 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Issue chooser config — rendered into <repo>/.github/ISSUE_TEMPLATE/ by
# adopt-standard.sh. Disables blank issues so every report uses a template,
# and routes security reports away from the public tracker.
blank_issues_enabled: false
contact_links:
- name: Security vulnerability (private)
url: https://github.com/Kenearos/Homeassistant/security/advisories/new
about: >-
Do NOT open a public issue for a security problem. Report privately per
SECURITY.md (no secrets/keys/tokens in the report; rotate first if leaked).
- name: Question / discussion
url: https://github.com/Kenearos/Homeassistant/discussions
about: For usage questions and open-ended discussion, use Discussions.
37 changes: 37 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
name: Feature request
about: Propose new functionality or a change to existing behaviour
title: "feat: <short summary>"
labels: [enhancement, triage]
assignees: []
---

<!--
Rendered into <repo>/.github/ISSUE_TEMPLATE/ by adopt-standard.sh.
If this proposes a change to a rule, contract, or default, expect to record an ADR
(docs/adr/NNNN-*.md) before it is implemented — see CONTRIBUTING.md.
-->

## Problem / motivation

<!-- What problem does this solve? Who feels the pain, and when? -->

## Proposed solution

<!-- What you'd like to happen. Be concrete. -->

## Alternatives considered

<!-- Other approaches and why they are worse/better. -->

## Scope & impact

- [ ] Backward compatible (`MINOR`)
- [ ] Breaking — consumers must act (`MAJOR`)
- [ ] Needs an **ADR** (decision about a rule/contract/default)
- [ ] Needs an **SOP** and/or **Policy** change
- [ ] Affects CI / deploy / secrets handling

## Additional context

<!-- Links, prior art, related issues/ADRs. -->
44 changes: 44 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!--
PULL_REQUEST_TEMPLATE.md — rendered into <repo>/.github/ by adopt-standard.sh.
The checklist is tied to SOP-001 (branch & merge) and the CI policy gates.
Keep the items; tailor wording to your repo. Delete inapplicable sections, not checks.
-->

## What & why

<!-- One or two sentences: what does this change do, and why now? Link the issue. -->

Closes #

## Type of change

- [ ] `feat` — new functionality
- [ ] `fix` — bug fix
- [ ] `docs` — documentation only
- [ ] `ci` / `refactor` / `test` / `chore`
- [ ] **Breaking change** (consumers must act — `!` / `BREAKING CHANGE:` in the commit)
- [ ] **Decision** — an ADR is included or updated (`docs/adr/NNNN-*.md`)

## SOP-001 (branch & merge) checklist

- [ ] Branched from `develop` with a short-lived `feature/<topic>` (no direct commits to `main`/`develop`).
- [ ] Commits follow **Conventional Commits**.
- [ ] Up to date with the base branch (rebased/merged); no merge conflicts.
- [ ] At least one **CODEOWNERS** reviewer is requested.
- [ ] `CHANGELOG.md` updated under `[Unreleased]` (if user-facing).

## Policy & security gates (must be green)

- [ ] `pre-commit run -a` passes locally (whitespace/EOF/YAML, **shellcheck**, **gitleaks**, **sops-encrypted-check**).
- [ ] CI `static-checks`, `test`, `build`, **`policy_check`** and **`security-scan`** stages pass.
- [ ] **No plaintext secrets** added — secrets are SOPS+age encrypted (`*.enc.*` / `*.sops.*` only). See `SECURITY.md`.
- [ ] Data traffic-light respected: nothing 🔴 RED (sensitive personal data / plaintext keys) committed.
- [ ] If this asserts a rule: an ADR records *why*, an SOP records *how*, and a Policy (+ `*_test.rego`) enforces it.

## How was this verified?

<!-- Commands run, environments tested, evidence. Be concrete and falsifiable. -->

## Rollback plan

<!-- If this is a risky change (deploy, migration, policy tightening): how to revert. -->
44 changes: 44 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# ci.yml — self-contained standards gate (VENDORED model).
#
# Rendered verbatim into <repo>/.github/workflows/ by adopt-standard.sh. The
# standard's Rego policies are vendored into this repo at .standards/policies/
# (also placed by adopt-standard.sh, pinned to .standards-version), and the gate
# logic lives in .standards/policy-gate.sh. CI installs conftest and runs the
# policies LOCALLY — no dependency on a remote (possibly private) standards repo,
# no cross-account reusable-workflow access, no PAT. Re-run adopt-standard.sh to
# update the vendored policies when you bump the pin.
#
# The same gate runs identically on Forgejo/Woodpecker — see the standard's
# ci/woodpecker/ (ADR-0002 dual-target CI). Add repo-native jobs (lint/test/build)
# below the gate; those are language-specific and owned by the repo.
name: ci

on:
push:
branches: [main, develop]
pull_request:

permissions:
contents: read

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
standards-gate:
runs-on: ubuntu-latest
env:
CONFTEST_VERSION: "0.68.2"
steps:
- uses: actions/checkout@v4

- name: Install conftest (pinned)
run: |
set -euo pipefail
url="https://github.com/open-policy-agent/conftest/releases/download/v${CONFTEST_VERSION}/conftest_${CONFTEST_VERSION}_Linux_x86_64.tar.gz"
curl -fsSL "$url" | sudo tar -xz -C /usr/local/bin conftest
conftest --version

- name: Policy gate (vendored standards policies)
run: bash .standards/policy-gate.sh
61 changes: 61 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# .pre-commit-config.yaml — rendered by adopt-standard.sh.
# Local mirror of the CI gates: hygiene + shell lint + secret scanning + policy.
# Install: pre-commit install | Run on everything: pre-commit run -a
# See ../SECURITY.md (no plaintext secrets) and SOP-001 (branch & merge).
minimum_pre_commit_version: "3.5.0"
fail_fast: false

repos:
# ── Baseline file hygiene ─────────────────────────────────────────────
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
# Preserve markdown hard line breaks (two trailing spaces).
args: [--markdown-linebreak-ext=md]
- id: end-of-file-fixer
- id: check-yaml
args: [--allow-multiple-documents]
- id: check-added-large-files
args: [--maxkb=1024]
- id: check-merge-conflict
- id: mixed-line-ending
args: [--fix=lf]

# ── Shell lint (POSIX / MinGW-safe scripts) ───────────────────────────
- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.10.0.1
hooks:
- id: shellcheck
args: [--severity=warning]

# ── Secret scanning — no plaintext secrets, ever ──────────────────────
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.4
hooks:
- id: gitleaks

# ── Local project hooks (no external pin; degrade gracefully) ─────────
- repo: local
hooks:
# Optional: validate config/manifests against the standard's Rego
# policies. Skipped automatically if `conftest` is not installed, so a
# missing optional binary never blocks a commit (graceful degradation).
- id: conftest
name: conftest (policy gate, optional)
entry: 'bash -c ''command -v conftest >/dev/null 2>&1 && conftest test --policy policies . || echo "conftest not installed - skipping policy gate"'''
language: system
pass_filenames: false
always_run: true

# Refuse to commit any *.sops.yaml / *.enc.yaml that is NOT actually
# SOPS-encrypted (i.e. missing the `sops:` metadata block). This catches
# the classic "saved the plaintext under the encrypted name" mistake.
# Implementation note: `grep -L` lists files MISSING the marker (no shell
# loop, no nested double quotes) so it survives the YAML/shell quoting layers.
# The marker is `sops:` (SOPS-YAML) or `"sops"` (SOPS-JSON).
- id: sops-encrypted-check
name: sops-encrypted-check (no plaintext under encrypted names)
entry: 'bash -c ''bad=$(grep -L -E ''"''"''^sops:|"sops"''"''"'' "$@"); if [ -n "$bad" ]; then echo "ERROR: named encrypted but missing SOPS metadata:"; echo "$bad"; exit 1; fi'' --'
language: system
files: '\.(sops|enc)\.(yaml|json)$'
1 change: 1 addition & 0 deletions .standards-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.0.0
Loading
Loading