Repository navigation
Epic: Formalize + enforce the org .gitignore minimum baseline (secrets L1) with per-repo extension (L2) #801
Copy link
Copy link
Open
Labels
enhancementFeature requestsFeature requests
Description
Tracked stories (DAG)
- Story: STANDARDIZE — .gitignore secrets baseline → standalone standard + marker-wrapped block #797 — STANDARDIZE (ROOT)
- Story: SEED + DISTRIBUTE — baseline into repo-template, bootstrap, and deploy sync #798 — SEED + DISTRIBUTE (blocked by Story: STANDARDIZE — .gitignore secrets baseline → standalone standard + marker-wrapped block #797)
- Story: ENFORCE — check_gitignore_baseline at error severity via the compliance engine #799 — ENFORCE (blocked by Story: STANDARDIZE — .gitignore secrets baseline → standalone standard + marker-wrapped block #797)
- Story: BACKFILL + REMEDIATE — bring the fleet to green on the gitignore baseline #800 — BACKFILL + REMEDIATE (blocked by Story: SEED + DISTRIBUTE — baseline into repo-template, bootstrap, and deploy sync #798 and Story: ENFORCE — check_gitignore_baseline at error severity via the compliance engine #799)
Formalize, distribute, and blockingly enforce an org-wide .gitignore minimum baseline — a language-agnostic secrets-only layer that every repo carries verbatim (L1), while each repo freely extends it with its own ecosystem/OS entries (L2).
Current state (verified, not greenfield)
A strong secrets-only baseline already exists at /.gitignore (396 lines) and is referenced by standards/push-protection.md. But it is under-formalized, under-adopted, and weakly enforced:
- Template gap —
repo-template/.gitignoreis 15 ad-hoc lines missing*.pem/*.key; new repos start non-compliant even against today's 3-substring check. - Adoption gap — only 4 of 10 repos carry the real baseline (
bmad-bgreat-suite,TalkTerm,ContentTwin,.github-private); the other 6 have hand-rolled gitignores with no cloud/SSH/tfvars coverage. - Enforcement gap —
pp_check_gitignore_secrets_block()checks only 3 substrings atwarningseverity; the documented rule ("MUST start from the baseline") is not actually enforced. - Distribution gap — detection only; nothing seeds or syncs the baseline (
grep gitignoreindeploy-standard-workflows.shandbootstrap-new-repo.sh= 0).
The DAG
#797 STANDARDIZE ── standalone standards/gitignore-standard.md (L1/L2 model) +
wrap the L1 secrets block in BEGIN/END markers in /.gitignore. [ROOT]
│
├── #798 SEED + DISTRIBUTE ── marker-wrapped block into repo-template +
│ bootstrap-new-repo.sh + deploy sync; shared idempotent
│ upsert_gitignore_baseline() (L2 preserved).
│
└── #799 ENFORCE ── check_gitignore_baseline: block present + unmodified
(hash match), severity ERROR, via the existing
compliance-audit engine. No new workflow. L2 never inspected.
│
#800 BACKFILL + REMEDIATE ── remediation hook + fleet back-fill of the 6
non-baseline repos so the now-blocking check goes green. (after #798 & #799)
Design — the minimum baseline
| Layer | Content | Owner | Enforced | Extendable |
|---|---|---|---|---|
| L1 secrets baseline | the 396-line block, wrapped in BEGIN/END petry-projects secrets baseline markers |
central (.github) |
yes — error/blocking, verbatim | no (drift = finding) |
| L2 ecosystem/OS | node_modules/, target/, __pycache__/, .DS_Store, … (github/gitignore templates) |
per-repo, below END marker | no | yes, freely |
Enforcement engine
Wired through the existing compliance-audit-and-improvement.yml (Job 1 → compliance-audit.sh / lib/push-protection.sh → findings → issues). We extend a check function, not add a workflow. Per decision, L1 lands at error severity (blocking tier).
Epic acceptance criteria
- Story: STANDARDIZE — .gitignore secrets baseline → standalone standard + marker-wrapped block #797:
gitignore-standard.mdpublished; L1 block marker-wrapped in/.gitignore; push-protection.md repointed. - Story: SEED + DISTRIBUTE — baseline into repo-template, bootstrap, and deploy sync #798: template + bootstrap + deploy carry the marker-wrapped block;
upsert_gitignore_baseline()unit-tested (L2 preserved). - Story: ENFORCE — check_gitignore_baseline at error severity via the compliance engine #799:
check_gitignore_baseline= error on missing/drifted, pass on present+unmodified; L2 extensions still pass; audit tests green. - Story: BACKFILL + REMEDIATE — bring the fleet to green on the gitignore baseline #800: 6 non-baseline repos back-filled (L2 preserved); remediation idempotent; compliance audit = 0 gitignore findings fleet-wide.
Notes / decisions
- Enforcement = error (blocking), via the compliance engine (per session decision).
- Optional hardening in Story: ENFORCE — check_gitignore_baseline at error severity via the compliance engine #799: a one-line
ci.ymlassertion to make it a per-repo required status check (true PR-time gate) — flagged, not required. - Ring/soak: harden severity behind the normal audit cadence; back-fill (Story: BACKFILL + REMEDIATE — bring the fleet to green on the gitignore baseline #800) does PR + admin-merge for ruleset-protected repos (add-to-project precedent).
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementFeature requestsFeature requests
Activity