Skip to content

Commit 64edc96

Browse files
authored
Merge pull request #12 from WebFirstLanguage/codex/project-governance
chore(governance): establish project policies and contribution templates
2 parents f62b365 + 8787f25 commit 64edc96

21 files changed

Lines changed: 2115 additions & 16 deletions
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
name: Bug report
2+
description: Report a reproducible problem with Scriptorium.
3+
title: "[Bug]: "
4+
body:
5+
- type: markdown
6+
attributes:
7+
value: |
8+
Describe one problem per report and link an existing issue if it covers the same problem.
9+
Share what you know; use "Unknown" for versions or details you cannot determine.
10+
11+
**This report and its attachments will be public.** Use synthetic examples and remove
12+
passwords, session cookies, CSRF tokens, personal information, private drafts, and site data.
13+
Do not attach a live database, raw production logs, or your complete deployment configuration.
14+
15+
Report suspected security vulnerabilities privately through
16+
[SECURITY.md](https://github.com/WebFirstLanguage/Scriptorium/blob/main/SECURITY.md).
17+
18+
- type: textarea
19+
id: summary
20+
attributes:
21+
label: What is broken?
22+
description: Describe the problem and who or what it affects. Use a title that names the failing behavior.
23+
placeholder: "For example: After saving a published page, the public page still shows the previous title."
24+
validations:
25+
required: true
26+
27+
- type: textarea
28+
id: environment
29+
attributes:
30+
label: Versions and environment
31+
description: |
32+
Include what you can determine; "Unknown" is fine. From the checkout used to run the site,
33+
`git rev-parse HEAD` identifies Scriptorium, `wfl --version` identifies WFL, and
34+
`git submodule status lib/scribe` shows the Scribe revision and checkout status.
35+
Include that output as-is. Describe relevant settings without credentials,
36+
private hostnames, or private filesystem paths.
37+
placeholder: |
38+
Scriptorium commit or version:
39+
WFL version:
40+
Scribe revision and checkout status:
41+
Operating system and version:
42+
Browser and version (if relevant):
43+
Deployment (local, container, reverse proxy, etc.):
44+
Theme and site extension (stock or customized):
45+
Data directory (default or configured):
46+
Fresh install or upgrade:
47+
validations:
48+
required: true
49+
50+
- type: textarea
51+
id: reproduction
52+
attributes:
53+
label: Steps to reproduce
54+
description: |
55+
Give the smallest steps that show the problem, including the route, account role,
56+
and synthetic input when relevant. A minimal WFL or template example is welcome.
57+
If you cannot reproduce it reliably, describe the sequence you observed.
58+
placeholder: |
59+
1. Start with ...
60+
2. Sign in as an admin/author and open ...
61+
3. Submit this sample input ...
62+
4. Observe ...
63+
validations:
64+
required: true
65+
66+
- type: textarea
67+
id: expected
68+
attributes:
69+
label: Expected behavior
70+
description: What should happen? Link relevant documentation if it helps explain the expectation.
71+
validations:
72+
required: true
73+
74+
- type: textarea
75+
id: actual
76+
attributes:
77+
label: Actual behavior
78+
description: What happened instead? Include the exact error or HTTP status when available, with sensitive values removed.
79+
validations:
80+
required: true
81+
82+
- type: dropdown
83+
id: frequency
84+
attributes:
85+
label: How often does it happen?
86+
options:
87+
- Every time
88+
- Sometimes
89+
- Observed once
90+
- Not sure
91+
validations:
92+
required: true
93+
94+
- type: textarea
95+
id: regression
96+
attributes:
97+
label: Last working version or recent changes
98+
description: Optional. Note a last working revision, recent upgrade, Scribe pin change, or theme/configuration change. Say if this is a fresh install.
99+
100+
- type: textarea
101+
id: evidence
102+
attributes:
103+
label: Relevant logs, screenshots, or minimal example
104+
description: |
105+
Optional. Paste only the relevant sanitized excerpt or attach a screenshot/example using
106+
synthetic data. Remove credentials, cookies, tokens, private content, and personal information.
107+
Include commands and actual results for any checks you already ran; tests are not required to report a bug.
108+
109+
- type: textarea
110+
id: workaround
111+
attributes:
112+
label: Workaround or additional context
113+
description: Optional. Describe any workaround, related issue, or other observation that may help reproduce the problem.

‎.github/ISSUE_TEMPLATE/config.yml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
blank_issues_enabled: true
2+
contact_links:
3+
- name: Report a security vulnerability
4+
url: https://github.com/WebFirstLanguage/Scriptorium/blob/main/SECURITY.md
5+
about: Use the private reporting process for vulnerabilities; do not publish exploit details or private site data in an issue.

‎.github/pull_request_template.md‎

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<!--
2+
Title: <type>(<optional scope>): <imperative summary>
3+
Example: fix(auth): reject expired sessions
4+
5+
Keep the headings below and replace the prompts with concrete details.
6+
Scale the detail to the change. Use "N/A — reason" for an inapplicable field;
7+
record missing checks as "Not run — reason", never as a pass. Drafts may mark
8+
unfinished evidence as pending. Keep the title and body aligned with the final diff.
9+
-->
10+
11+
## Summary
12+
13+
<!-- Explain the problem and resulting behavior. Include a brief before/after
14+
example when useful, observable acceptance criteria, and related issue links. -->
15+
16+
## Changes
17+
18+
<!-- List the material changes and why they are needed. Include only details
19+
that help a reviewer assess the implementation; omit the work-session history. -->
20+
21+
## Compatibility and risk
22+
23+
- **Risk class and reason:** <!-- R0, R1, R2, or R3; see testing.md. -->
24+
- **Affected contracts:** <!-- URLs, schema/data/uploads, configuration, themes,
25+
extension hooks, runtime requirements, or the Scribe pin; say none if unaffected. -->
26+
- **Upgrade and recovery:** <!-- Migration, backup, rollback or forward-repair
27+
steps. Link the approved transition plan for a breaking change, or explain N/A. -->
28+
- **Remaining risks or gaps:** <!-- Untested boundaries, limitations, and any
29+
exception with its approval, scope, expiry, and follow-up issue; or none. -->
30+
31+
## Validation
32+
33+
- **Tested revision and environment:** <!-- Commit, OS, relevant tool versions;
34+
include WFL and pinned Scribe revisions for runtime checks. -->
35+
- **Regression evidence:** <!-- Intended failure before the fix and passing
36+
result afterward; Green before/after for a refactor; explain N/A for prose. -->
37+
38+
| Check or exact command | Result and evidence |
39+
|---|---|
40+
| <!-- Required automated check --> | <!-- Actual result, counts or CI run link; identify failures and checks not run. --> |
41+
| <!-- Affected HTTP/UI, security, accessibility, or recovery check --> | <!-- Setup, expected/actual outcome, and evidence; or N/A with reason. --> |
42+
43+
## Checklist
44+
45+
- [ ] The title, summary, and risk assessment match the final diff.
46+
- [ ] Required validation is recorded above; failures and missing checks are explicit.
47+
- [ ] Documentation, examples, and upgrade/recovery guidance are updated where applicable.
48+
- [ ] I reviewed the diff for repository hygiene, secrets, and private site data.
49+
50+
Follow [CONTRIBUTING.md](https://github.com/WebFirstLanguage/Scriptorium/blob/main/CONTRIBUTING.md),
51+
[testing.md](https://github.com/WebFirstLanguage/Scriptorium/blob/main/testing.md), and
52+
[REPOSITORY_HYGIENE.md](https://github.com/WebFirstLanguage/Scriptorium/blob/main/REPOSITORY_HYGIENE.md).
53+
54+
Report undisclosed vulnerabilities privately using [SECURITY.md](https://github.com/WebFirstLanguage/Scriptorium/blob/main/SECURITY.md).

‎.github/workflows/governance.yml‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Governance
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
workflow_dispatch:
9+
10+
permissions:
11+
contents: read
12+
13+
concurrency:
14+
group: governance-${{ github.workflow }}-${{ github.ref }}
15+
cancel-in-progress: true
16+
17+
jobs:
18+
repository-checks:
19+
name: Repository checks (${{ matrix.os }})
20+
strategy:
21+
fail-fast: false
22+
matrix:
23+
os: [ubuntu-latest, windows-latest]
24+
runs-on: ${{ matrix.os }}
25+
timeout-minutes: 10
26+
steps:
27+
- uses: actions/checkout@v4
28+
with:
29+
persist-credentials: false
30+
submodules: recursive
31+
- uses: actions/setup-python@v5
32+
with:
33+
python-version: '3.12'
34+
- name: Test repository tooling
35+
run: python -m unittest discover -s tests/tooling -v
36+
- name: Check repository hygiene
37+
run: python scripts/check_repo_hygiene.py

‎.github/workflows/update-scribe.yml‎

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
# lib/scribe to the tip of Scribe's main and opens a PR with the intervening
77
# Scribe commits in the body, so the bump is reviewed rather than silent.
88
#
9-
# Note on CI: the PR is opened with the built-in GITHUB_TOKEN, and GitHub does
10-
# not fire `push` / `pull_request` workflow events for anything that token
11-
# creates. No test workflow exists in this repo today, so nothing is missed —
12-
# but if one is added, it will NOT run on these auto-generated PRs. Swap in a
13-
# PAT or GitHub App token at that point if you want checks on them.
9+
# Note on CI: GITHUB_TOKEN-created PR runs may require Maintainer approval.
10+
# Approve the pending Governance run, or use Run workflow on the PR branch;
11+
# verify that the successful run covers the current revision before merging.
12+
# Runtime tests also need recorded results; see testing.md. No extra token is
13+
# needed for the manual Governance workflow.
14+
# https://docs.github.com/en/actions/concepts/security/github_token
1415
#
1516
# To bump by hand instead, run scripts/update-scribe.sh.
1617
name: Update Scribe
@@ -106,7 +107,11 @@ jobs:
106107
git push -u $force origin "$branch"
107108
108109
{
109-
echo "Bumps the \`lib/scribe\` submodule from \`$BEFORE\` to \`$AFTER\`."
110+
echo '## Summary'
111+
echo
112+
echo "Update the \`lib/scribe\` pin from \`$BEFORE\` to \`$AFTER\` to pick up the latest upstream main changes while keeping checkouts reproducible."
113+
echo
114+
echo '## Changes'
110115
echo
111116
echo "Scribe commits picked up:"
112117
echo
@@ -115,7 +120,38 @@ jobs:
115120
echo '```'
116121
echo
117122
echo "Opened automatically by \`.github/workflows/update-scribe.yml\`."
118-
echo "Review Scribe's changes and run the Scriptorium suites before merging."
123+
echo
124+
echo '## Compatibility and risk'
125+
echo
126+
echo '- **Risk class and reason:** R2 (Scribe dependency pin); raise the class if the upstream diff affects a higher-risk boundary.'
127+
echo '- **Affected contracts:** Scribe pin, template rendering, escaping and safe markers, Markdown, and theme output. Review the upstream diff to identify the changed paths.'
128+
echo '- **Upgrade and recovery:** Compatibility and migration requirements are not yet verified. To undo the pin change, revert the bump commit and update submodules to restore the previous pin. Any migration needs its own tested recovery plan.'
129+
echo '- **Remaining risks or gaps:** Upstream compatibility review and affected rendering journeys are pending. No policy exception has been recorded.'
130+
echo
131+
echo '## Validation'
132+
echo
133+
echo '- **Tested revision and environment:** Pending. Record the tested Scriptorium and Scribe revisions, OS/configuration, `wfl --version`, and relevant tool versions with the results.'
134+
echo '- **Regression evidence:** Pending upstream diff review. Record the required before/after evidence for affected behavior, or explain why a check does not apply.'
135+
echo
136+
echo '| Check or exact command | Result and evidence |'
137+
echo '|---|---|'
138+
echo '| `python scripts/run_tests.py --include-scribe` | Not run — this workflow prepares the dependency bump. Record the local and upstream suite results, including failures. |'
139+
echo '| `python -m unittest discover -s tests/tooling -v` | Pending — Governance results are not verified by this workflow. Link results for the current revision. |'
140+
echo '| `python scripts/check_repo_hygiene.py` | Pending — Governance results are not verified by this workflow. Link results for the current revision. |'
141+
echo '| Affected HTTP/UI rendering journeys | Not run — upstream diff review is needed to identify affected paths. Record setup, expected/actual outcome, and evidence. |'
142+
echo
143+
echo 'Approve any pending Governance run, or run Governance manually on this branch. Verify that successful checks cover the current revision before merging.'
144+
echo
145+
echo '## Checklist'
146+
echo
147+
echo '- [ ] The title, summary, and risk assessment match the final diff.'
148+
echo '- [ ] Required validation is recorded above; failures and missing checks are explicit.'
149+
echo '- [ ] Documentation, examples, and upgrade/recovery guidance are updated where applicable.'
150+
echo '- [ ] I reviewed the diff for repository hygiene, secrets, and private site data.'
151+
echo
152+
echo 'Follow [CONTRIBUTING.md](https://github.com/WebFirstLanguage/Scriptorium/blob/main/CONTRIBUTING.md), [testing.md](https://github.com/WebFirstLanguage/Scriptorium/blob/main/testing.md), and [REPOSITORY_HYGIENE.md](https://github.com/WebFirstLanguage/Scriptorium/blob/main/REPOSITORY_HYGIENE.md).'
153+
echo
154+
echo 'Report undisclosed vulnerabilities privately using [SECURITY.md](https://github.com/WebFirstLanguage/Scriptorium/blob/main/SECURITY.md).'
119155
} > /tmp/pr-body.md
120156
121157
gh pr create \

‎.gitignore‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,31 @@ node_modules/
2121
# Uploaded media (runtime)
2222
static/uploads/*
2323
!static/uploads/.gitkeep
24+
25+
# Local site data, backups, and test/tool outputs
26+
/data/
27+
/target/
28+
*.sqlite
29+
*.sqlite3
30+
*.db-journal
31+
*.sqlite-journal
32+
*.sqlite3-journal
33+
*.sqlite-wal
34+
*.sqlite-shm
35+
*.sqlite3-wal
36+
*.sqlite3-shm
37+
*.log
38+
39+
# Local credentials and TLS material (never commit deployment configuration)
40+
.env
41+
.env.*
42+
*.key
43+
*.pem
44+
*.p12
45+
*.pfx
46+
47+
# Python tooling
48+
__pycache__/
49+
*.py[cod]
50+
.venv/
51+
.pytest_cache/

‎.repo-hygiene.toml‎

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Concrete enforcement for REPOSITORY_HYGIENE.md. Changes require review of
2+
# the policy reason, not just a wider allowlist to make the checker pass.
3+
schema = 1
4+
5+
[root]
6+
allowed-files = [
7+
".gitignore", ".gitmodules", ".repo-hygiene.toml", ".wflcfg",
8+
"AGENTS.md", "AI_POLICY.md", "CLAUDE.md", "CODE_OF_CONDUCT.md",
9+
"CONTRIBUTING.md", "GOVERNANCE.md", "LICENSE", "README.md",
10+
"REPOSITORY_HYGIENE.md", "SECURITY.md", "main.wfl", "testing.md",
11+
]
12+
allowed-dirs = [
13+
".github", "admin", "app", "docs", "lib", "scripts", "static",
14+
"TestPrograms", "tests", "themes",
15+
]
16+
17+
[required]
18+
files = [
19+
".gitignore", ".gitmodules", ".repo-hygiene.toml", ".wflcfg",
20+
"AGENTS.md", "AI_POLICY.md", "CLAUDE.md", "CODE_OF_CONDUCT.md",
21+
"CONTRIBUTING.md", "GOVERNANCE.md", "LICENSE", "README.md",
22+
"REPOSITORY_HYGIENE.md", "SECURITY.md", "main.wfl", "testing.md",
23+
"docs/ARCHITECTURE.md", "docs/PROJECT-LAYOUT.md", "docs/THEMING.md",
24+
"scripts/check_repo_hygiene.py", "scripts/run_tests.py",
25+
"tests/tooling/test_repo_hygiene.py", "tests/tooling/test_run_tests.py",
26+
".github/pull_request_template.md", ".github/workflows/governance.yml",
27+
]
28+
# These paths must remain Git gitlinks; their contents are upstream-owned.
29+
gitlinks = ["lib/scribe"]
30+
31+
[forbidden]
32+
# Match path components / base names case-insensitively, at any depth.
33+
dirs = [
34+
"__pycache__", ".pytest_cache", ".mypy_cache", ".ruff_cache",
35+
"node_modules", ".venv", "venv", "target", ".cache",
36+
]
37+
names = [".DS_Store", "Thumbs.db", "settings.local.json", "id_rsa", "id_ed25519"]
38+
patterns = [
39+
"*.db", "*.db-*", "*.sqlite", "*.sqlite-*", "*.sqlite3", "*.sqlite3-*",
40+
"*.log", "*.pyc", "*.pyo", "*.orig", "*.rej", "*.tmp", "*.bak",
41+
"*_debug.txt", "*.ast.txt", "*.lex.txt", "*.exe", "*.dll", "*.msi",
42+
".env", ".env.*", "*.key", "*.pem", "*.p12", "*.pfx",
43+
"credentials.json", "credentials.*.json", "secrets.json", "secrets.*.json",
44+
]
45+
# Mutable application state. Only the existing empty upload placeholder ships.
46+
paths = ["data", "static/uploads"]
47+
allowed-placeholders = ["static/uploads/.gitkeep"]
48+
49+
[links]
50+
# Check local inline links/images and reference-link definitions in these files.
51+
# Fragments, external URLs, code fences, and paths within gitlinks are skipped.
52+
files = [
53+
"README.md", "CLAUDE.md", "AGENTS.md", "GOVERNANCE.md", "CONTRIBUTING.md",
54+
"CODE_OF_CONDUCT.md", "AI_POLICY.md", "SECURITY.md", "REPOSITORY_HYGIENE.md",
55+
"testing.md",
56+
]

‎AGENTS.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Repository guidelines
2+
3+
Read [CLAUDE.md](CLAUDE.md) first. It is the canonical shared agent guide for
4+
Scriptorium, including architecture constraints, development commands, and
5+
links to the binding root governance policies.
6+
7+
This file is an adapter, not a second policy source. Update `CLAUDE.md` and the
8+
relevant root policy when guidance changes.

0 commit comments

Comments
 (0)