Security Hygiene
Security Philosophy
This is a self-modifying system. Security should work like a helpful companion, not an adversarial checkpoint — zen and the art of programming. Tools protect by default, guide by suggestion, block only when there is a real reason.
Threat Surface
| Vector |
Risk |
Check |
| Path traversal |
Skill names used in file paths could escape directory |
Sanitize all skill names: alphanumeric, hyphens, underscores only. Reject .., /, \. |
| YAML deserialization |
Unsafe YAML loading executes arbitrary code |
Use safe parsing only (yaml.safe_load or equivalent). Never yaml.load with untrusted input. |
| Data poisoning |
Append-only JSONL could contain injected entries |
Validate entries on read: check schema, reject oversized entries, verify timestamps are monotonic. |
| Permission bypass |
Automated workflows might skip user confirmation |
Never bypass user confirmation for skill application, even in YOLO mode. YOLO applies to GSD workflow commands, not skill modifications. |
| Cross-project leakage |
User-level skills might expose project-specific patterns |
User-level skills must be generic. Project-specific patterns stay in project-level skills. |
| Observation privacy |
Pattern data could leak into shared repos |
.planning/patterns/ must be in .gitignore. Verify on any git operation. |
Content Hygiene Rules
When processing community-contributed content (skills, chipsets, LoRA adapters):
- Check for embedded commands or script execution
- Verify YAML does not contain unsafe tags (
!!python/object, etc.)
- Validate that skill descriptions match their actual content
- Quarantine new community content for review before activation
Privacy Tier Taxonomy (4-tier, OOPS-08-P03)
All telemetry, observation data, and skill artefacts are classified into one
of four privacy tiers. Telemetry writers MUST stamp every record with its
tier and MUST NOT mix tiers in a single sink.
| Tier |
Name |
Description |
Examples |
| A |
Public |
No PII, no proprietary content; safe to publish externally. |
Open-source skill descriptions, public release notes, anonymised aggregate metrics. |
| B |
Internal |
Non-PII operational data; safe to share within the project team. |
Phase activity counts, commit-type distributions, hook firing rates, build-time profiles. |
| C |
Sensitive |
PII, credentials, authentication tokens, individual session transcripts. |
.env contents, OAuth tokens, individual user prompts, raw conversation logs. |
| D |
Restricted |
Regulated data, proprietary IP, Fox Companies content. |
.planning/fox-companies/ artefacts, wasteland/ content, customer-identifiable records, anything subject to legal hold. |
Defaults and enforcement:
- New telemetry writers default to Tier B unless an explicit tier label
is supplied at construction.
- Tier C data MUST be encrypted at rest and MUST be excluded from any
artefact published outside the local repository (no
git push of files
containing Tier C content; no FTP sync; no inclusion in release notes).
- Tier D data MUST never leave the
.planning/ tree or
wasteland/ branch. Surface alignments in conversation only; never
commit Tier D content to a public-facing path.
- Mixed-tier sinks are FORBIDDEN — a writer that mixes Tier A and Tier C
records loses the ability to safely publish the Tier A subset.
Referenced by C5 W3.P6 tool-tracker (telemetry writer wiring) and the
post-tool-use observation hook.
Authoring around the leak-scanner — don't re-trip the control (Lesson #10462)
The release-history publisher (tools/release-history/publish.mjs, leakScan) runs
a hard leak-scan gate over every published chapter. Its effective patterns combine
committed base patterns with operator-private patterns loaded from the gitignored
release-history.local.json, so the scan is operator-machine-specific: a fresh
CI checkout sees only the base patterns and never the local ones.
Two failure modes recur whenever you DOCUMENT leak-scan or security-hardening work:
- The control's own documentation re-trips it. A retrospective that quotes a
leak pattern verbatim (e.g. v1.49.588 quoting the narrowed private-path regex
it was describing) matches that pattern and is HARD-BLOCKED — even though it
contains no real secret.
- The recursion trap. Documenting the fix for #1 by enumerating the private
literals the control guards (company / email / credential-var) embeds those
values into published content — a genuine leak the scanner correctly blocks.
The v1.49.916 retrospective re-tripped exactly this way while documenting the
v916 AC7 allowlist fix.
Authoring rule: describe the pattern, never quote the literal. In release notes,
retrospectives, or docs that touch leak-scan work, refer to a pattern by name or
shape ("the company-name local pattern", "the credential-var form") — never paste
the regex source and never paste the private value.
Allowlist-vs-scrub decision rule:
- The doc legitimately quotes a leak PATTERN (a regex, for self-referential
documentation) → add a narrow
leak_scan_allowlist entry in the committed
release-history.config.json, keyed on the EXACT version + file + pattern
source, with a reason. Never widen to a global pattern exemption.
- The content embeds a genuinely-private VALUE → SCRUB the value from the
content. Never allowlist a private value into published output — the allowlist is
for pattern-quoting docs only, never for secrets.
This pairs the loud surface (the leak-scan gate) with the authoring discipline that
keeps it from firing on its own documentation. See
docs/failure-mode-contracts.md (#10427
silent-vs-loud surfaces) and
docs/known-unwired-ledger-discipline.md
(#10461 gate-enforce-every-runnable-surface + drift-guard).
The Staging Layer Principle
"The user's ability to work should be reasonable. Security should also be reasonable. We strive for the clean intersection." Do not over-alert. Do not create friction for normal operations. Surface findings only when something genuinely warrants attention.
1---2name: security-hygiene3description: >4 Security hygiene for GSD's self-modifying skill and agent system.5 Use this skill whenever: creating, editing, or deleting skill files6 (.claude/skills/, .claude/commands/), modifying agent definitions7 (.claude/agents/), working with YAML configuration or chipset files,8 handling JSONL observation data (.planning/patterns/), processing9 community-contributed skills or chipsets, any file path operations10 that could involve user input, or when installing/updating11 project-claude configuration. Also activates for discussions about12 skill-creator security, trust models, or content hygiene.13user-invocable: true14version: 1.0.015format: 2025-10-0216triggers:17 - "for discussions about skill-creator security, trust models, or content hygiene"18updated: 2026-04-2519status: ACTIVE20---2122# Security Hygiene2324## Security Philosophy2526This is a self-modifying system. Security should work like a helpful companion, not an adversarial checkpoint — zen and the art of programming. Tools protect by default, guide by suggestion, block only when there is a real reason.2728## Threat Surface2930| Vector | Risk | Check |31|---|---|---|32| **Path traversal** | Skill names used in file paths could escape directory | Sanitize all skill names: alphanumeric, hyphens, underscores only. Reject `..`, `/`, `\`. |33| **YAML deserialization** | Unsafe YAML loading executes arbitrary code | Use safe parsing only (`yaml.safe_load` or equivalent). Never `yaml.load` with untrusted input. |34| **Data poisoning** | Append-only JSONL could contain injected entries | Validate entries on read: check schema, reject oversized entries, verify timestamps are monotonic. |35| **Permission bypass** | Automated workflows might skip user confirmation | **Never bypass user confirmation for skill application**, even in YOLO mode. YOLO applies to GSD workflow commands, not skill modifications. |36| **Cross-project leakage** | User-level skills might expose project-specific patterns | User-level skills must be generic. Project-specific patterns stay in project-level skills. |37| **Observation privacy** | Pattern data could leak into shared repos | `.planning/patterns/` must be in `.gitignore`. Verify on any git operation. |3839## Content Hygiene Rules4041When processing community-contributed content (skills, chipsets, LoRA adapters):42- Check for embedded commands or script execution43- Verify YAML does not contain unsafe tags (`!!python/object`, etc.)44- Validate that skill descriptions match their actual content45- Quarantine new community content for review before activation4647## Privacy Tier Taxonomy (4-tier, OOPS-08-P03)4849All telemetry, observation data, and skill artefacts are classified into one50of four privacy tiers. Telemetry writers MUST stamp every record with its51tier and MUST NOT mix tiers in a single sink.5253| Tier | Name | Description | Examples |54|------|------|-------------|----------|55| **A** | **Public** | No PII, no proprietary content; safe to publish externally. | Open-source skill descriptions, public release notes, anonymised aggregate metrics. |56| **B** | **Internal** | Non-PII operational data; safe to share within the project team. | Phase activity counts, commit-type distributions, hook firing rates, build-time profiles. |57| **C** | **Sensitive** | PII, credentials, authentication tokens, individual session transcripts. | `.env` contents, OAuth tokens, individual user prompts, raw conversation logs. |58| **D** | **Restricted** | Regulated data, proprietary IP, Fox Companies content. | `.planning/fox-companies/` artefacts, `wasteland/` content, customer-identifiable records, anything subject to legal hold. |5960Defaults and enforcement:6162- New telemetry writers default to **Tier B** unless an explicit tier label63 is supplied at construction.64- **Tier C** data MUST be encrypted at rest and MUST be excluded from any65 artefact published outside the local repository (no `git push` of files66 containing Tier C content; no FTP sync; no inclusion in release notes).67- **Tier D** data MUST never leave the `.planning/` tree or68 `wasteland/` branch. Surface alignments in conversation only; never69 commit Tier D content to a public-facing path.70- Mixed-tier sinks are FORBIDDEN — a writer that mixes Tier A and Tier C71 records loses the ability to safely publish the Tier A subset.7273Referenced by C5 W3.P6 tool-tracker (telemetry writer wiring) and the74post-tool-use observation hook.7576## Authoring around the leak-scanner — don't re-trip the control (Lesson #10462)7778The release-history publisher (`tools/release-history/publish.mjs`, `leakScan`) runs79a hard leak-scan gate over every published chapter. Its effective patterns combine80committed base patterns with operator-private patterns loaded from the gitignored81`release-history.local.json`, so the scan is **operator-machine-specific**: a fresh82CI checkout sees only the base patterns and never the local ones.8384Two failure modes recur whenever you DOCUMENT leak-scan or security-hardening work:85861. **The control's own documentation re-trips it.** A retrospective that quotes a87 leak *pattern* verbatim (e.g. v1.49.588 quoting the narrowed private-path regex88 it was describing) matches that pattern and is HARD-BLOCKED — even though it89 contains no real secret.902. **The recursion trap.** Documenting the *fix* for #1 by enumerating the private91 literals the control guards (company / email / credential-var) embeds those92 values into published content — a genuine leak the scanner correctly blocks.93 The v1.49.916 retrospective re-tripped exactly this way while documenting the94 v916 AC7 allowlist fix.9596**Authoring rule: describe the pattern, never quote the literal.** In release notes,97retrospectives, or docs that touch leak-scan work, refer to a pattern by name or98shape ("the company-name local pattern", "the credential-var form") — never paste99the regex source and never paste the private value.100101**Allowlist-vs-scrub decision rule:**102103- The doc legitimately quotes a leak **PATTERN** (a regex, for self-referential104 documentation) → add a narrow `leak_scan_allowlist` entry in the committed105 `release-history.config.json`, keyed on the EXACT `version` + `file` + `pattern`106 source, with a `reason`. Never widen to a global pattern exemption.107- The content embeds a genuinely-private **VALUE** → **SCRUB the value** from the108 content. Never allowlist a private value into published output — the allowlist is109 for pattern-quoting docs only, never for secrets.110111This pairs the loud surface (the leak-scan gate) with the authoring discipline that112keeps it from firing on its own documentation. See113[`docs/failure-mode-contracts.md`](../../../docs/failure-mode-contracts.md) (#10427114silent-vs-loud surfaces) and115[`docs/known-unwired-ledger-discipline.md`](../../../docs/known-unwired-ledger-discipline.md)116(#10461 gate-enforce-every-runnable-surface + drift-guard).117118## The Staging Layer Principle119120"The user's ability to work should be reasonable. Security should also be reasonable. We strive for the clean intersection." Do not over-alert. Do not create friction for normal operations. Surface findings only when something genuinely warrants attention.