feat: add canon_traditions meta table + validator (#1539) - #1587

Closed
CraigBuckmaster wants to merge 1 commit into
masterfrom
feature/hwgtb-p1-02-canon-traditions-schema
Closed

feat: add canon_traditions meta table + validator (#1539)#1587
CraigBuckmaster wants to merge 1 commit into
masterfrom
feature/hwgtb-p1-02-canon-traditions-schema

Conversation

@CraigBuckmaster

Copy link
Copy Markdown
Owner

What this does

Introduces the canon_traditions meta table — schema for the four major canonical traditions (Protestant, Catholic, Eastern Orthodox, Ethiopian Tewahedo). Seeds content/meta/canon_traditions.json as an empty array; the four seeded entries land in HWGTB-P1-05 (#1542).

Closes

Closes#1539

Changes

  • New filecontent/meta/canon_traditions.json — empty array.
  • _tools/build_sqlite_schema.pyCREATE TABLE canon_traditions + idx_canon_traditions_sort.
  • _tools/build_sqlite_loaders.pypopulate_canon_traditions() loader.
  • _tools/build_sqlite.py — loader imported + registered in pipeline.
  • _tools/schema_validator.py — new CANON TRADITIONS section:
    • Required keys: id, label, book_count, canon_list
    • id is snake_case and unique
    • book_count equals the total canon_list[].books[] length
    • canon_list[].books[] validated per the issue. Books outside books.json (deuterocanon, pseudepigrapha, etc.) are tolerated with an informational log — they're expected for non-Protestant traditions — provided they pass the snake_case id shape.
  • _tools/validate_sqlite.py — DB-side book_count vs canon_list_json consistency check.
  • app/assets/db-manifest.json — content hash bump.

How I verified

Smoke test with a dummy tradition (3 books: genesis/exodus/matthew, book_count=3):

  • Positive path: schema_validator + build + validate_sqlite all pass.
  • Negative path: set book_count=99, confirmed both schema_validator and validate_sqlite emit book_count=99 listed=3 failures.

Final committed state (empty array):

  • python _tools/schema_validator.py136483 passed, 77 failed (same pre-existing set as master), 0 new failures ✅
  • python _tools/build_sqlite.pycanon_traditions: 0 rows
  • python _tools/validate_sqlite.py94 passed, 0 failed, 2 warnings ✅

Out of scope

Rollback

Revert this PR. Table is recreated from schema on each build so no migration cleanup.


Generated by Claude Code

Introduces the canon_traditions schema for the four major canonical
traditions (Protestant, Catholic, Eastern Orthodox, Ethiopian
Tewahedo) feeding the Canon Comparison screen. Seeds
content/meta/canon_traditions.json as an empty array; the four
seeded traditions land in HWGTB-P1-05.
schema_validator.py enforces id shape, required keys, and a
book_count-vs-canon_list consistency check. Books outside the 66-book
Protestant biblical canon are tolerated (deuterocanon / pseudepigrapha
will live there) provided they are snake_case ids. validate_sqlite.py
asserts the DB-side book_count invariant.
Closes#1539https://claude.ai/code/session_01PHELDhvq1dxY36oL5Gguad
@github-actions

Copy link
Copy Markdown

Content Pipeline Results

✅ All pipeline checks passed

StepStatusDetails
Schema Validation136483 passed, 77 failed
Build DB
DB Integrity94 passed, 0 failed

Content Pipeline — Quality & Accuracy Report

All content checks passed

Scope: 0 chapter(s) across 0 book(s)


Generated by ci_content_check.py

@github-actions

Copy link
Copy Markdown

Test Results

✅ All tests passed

PassedFailedTotal
Tests✅ 3474❌ 03474
Suites✅ 469❌ 0469

Coverage

StatementsBranchesFunctionsLines

⏱️ Duration: 82.4s

@CraigBuckmaster

Copy link
Copy Markdown
OwnerAuthor

Closing as superseded by #1590.

Both PRs modify the same _tools/build_sqlite_*.py schema files plus content/meta/canon_traditions.json — this PR seeds canon_traditions as an empty array and #1590 seeds it with the full 4 entries. #1590 contains the strict superset of this PR's diff.

Keeping #1590 and closing here to avoid a merge conflict on the schema files.

@CraigBuckmaster
CraigBuckmaster deleted the feature/hwgtb-p1-02-canon-traditions-schema branch April 23, 2026 20:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[HWGTB-P1-02] Schema: canon_traditions meta table

2 participants

@CraigBuckmaster@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: add canon_traditions meta table + validator (#1539) - #1587

Closed
CraigBuckmaster wants to merge 1 commit into
masterfrom
feature/hwgtb-p1-02-canon-traditions-schema
Closed

feat: add canon_traditions meta table + validator (#1539)#1587
CraigBuckmaster wants to merge 1 commit into
masterfrom
feature/hwgtb-p1-02-canon-traditions-schema

Conversation

@CraigBuckmaster

Copy link
Copy Markdown
Owner

What this does

Introduces the canon_traditions meta table — schema for the four major canonical traditions (Protestant, Catholic, Eastern Orthodox, Ethiopian Tewahedo). Seeds content/meta/canon_traditions.json as an empty array; the four seeded entries land in HWGTB-P1-05 (#1542).

Closes

Closes#1539

Changes

  • New filecontent/meta/canon_traditions.json — empty array.
  • _tools/build_sqlite_schema.pyCREATE TABLE canon_traditions + idx_canon_traditions_sort.
  • _tools/build_sqlite_loaders.pypopulate_canon_traditions() loader.
  • _tools/build_sqlite.py — loader imported + registered in pipeline.
  • _tools/schema_validator.py — new CANON TRADITIONS section:
    • Required keys: id, label, book_count, canon_list
    • id is snake_case and unique
    • book_count equals the total canon_list[].books[] length
    • canon_list[].books[] validated per the issue. Books outside books.json (deuterocanon, pseudepigrapha, etc.) are tolerated with an informational log — they're expected for non-Protestant traditions — provided they pass the snake_case id shape.
  • _tools/validate_sqlite.py — DB-side book_count vs canon_list_json consistency check.
  • app/assets/db-manifest.json — content hash bump.

How I verified

Smoke test with a dummy tradition (3 books: genesis/exodus/matthew, book_count=3):

  • Positive path: schema_validator + build + validate_sqlite all pass.
  • Negative path: set book_count=99, confirmed both schema_validator and validate_sqlite emit book_count=99 listed=3 failures.

Final committed state (empty array):

  • python _tools/schema_validator.py136483 passed, 77 failed (same pre-existing set as master), 0 new failures ✅
  • python _tools/build_sqlite.pycanon_traditions: 0 rows
  • python _tools/validate_sqlite.py94 passed, 0 failed, 2 warnings ✅

Out of scope

Rollback

Revert this PR. Table is recreated from schema on each build so no migration cleanup.


Generated by Claude Code

Introduces the canon_traditions schema for the four major canonical
traditions (Protestant, Catholic, Eastern Orthodox, Ethiopian
Tewahedo) feeding the Canon Comparison screen. Seeds
content/meta/canon_traditions.json as an empty array; the four
seeded traditions land in HWGTB-P1-05.
schema_validator.py enforces id shape, required keys, and a
book_count-vs-canon_list consistency check. Books outside the 66-book
Protestant biblical canon are tolerated (deuterocanon / pseudepigrapha
will live there) provided they are snake_case ids. validate_sqlite.py
asserts the DB-side book_count invariant.
Closes#1539https://claude.ai/code/session_01PHELDhvq1dxY36oL5Gguad
@github-actions

Copy link
Copy Markdown

Content Pipeline Results

✅ All pipeline checks passed

StepStatusDetails
Schema Validation136483 passed, 77 failed
Build DB
DB Integrity94 passed, 0 failed

Content Pipeline — Quality & Accuracy Report

All content checks passed

Scope: 0 chapter(s) across 0 book(s)


Generated by ci_content_check.py

@github-actions

Copy link
Copy Markdown

Test Results

✅ All tests passed

PassedFailedTotal
Tests✅ 3474❌ 03474
Suites✅ 469❌ 0469

Coverage

StatementsBranchesFunctionsLines

⏱️ Duration: 82.4s

@CraigBuckmaster

Copy link
Copy Markdown
OwnerAuthor

Closing as superseded by #1590.

Both PRs modify the same _tools/build_sqlite_*.py schema files plus content/meta/canon_traditions.json — this PR seeds canon_traditions as an empty array and #1590 seeds it with the full 4 entries. #1590 contains the strict superset of this PR's diff.

Keeping #1590 and closing here to avoid a merge conflict on the schema files.

@CraigBuckmaster
CraigBuckmaster deleted the feature/hwgtb-p1-02-canon-traditions-schema branch April 23, 2026 20:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[HWGTB-P1-02] Schema: canon_traditions meta table

2 participants

@CraigBuckmaster@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add canon_traditions meta table + validator (#1539) - #1587

Closed
CraigBuckmaster wants to merge 1 commit into
masterfrom
feature/hwgtb-p1-02-canon-traditions-schema
Closed

feat: add canon_traditions meta table + validator (#1539)#1587
CraigBuckmaster wants to merge 1 commit into
masterfrom
feature/hwgtb-p1-02-canon-traditions-schema

Conversation

@CraigBuckmaster

Copy link
Copy Markdown
Owner

What this does

Introduces the canon_traditions meta table — schema for the four major canonical traditions (Protestant, Catholic, Eastern Orthodox, Ethiopian Tewahedo). Seeds content/meta/canon_traditions.json as an empty array; the four seeded entries land in HWGTB-P1-05 (#1542).

Closes

Closes#1539

Changes

  • New filecontent/meta/canon_traditions.json — empty array.
  • _tools/build_sqlite_schema.pyCREATE TABLE canon_traditions + idx_canon_traditions_sort.
  • _tools/build_sqlite_loaders.pypopulate_canon_traditions() loader.
  • _tools/build_sqlite.py — loader imported + registered in pipeline.
  • _tools/schema_validator.py — new CANON TRADITIONS section:
    • Required keys: id, label, book_count, canon_list
    • id is snake_case and unique
    • book_count equals the total canon_list[].books[] length
    • canon_list[].books[] validated per the issue. Books outside books.json (deuterocanon, pseudepigrapha, etc.) are tolerated with an informational log — they're expected for non-Protestant traditions — provided they pass the snake_case id shape.
  • _tools/validate_sqlite.py — DB-side book_count vs canon_list_json consistency check.
  • app/assets/db-manifest.json — content hash bump.

How I verified

Smoke test with a dummy tradition (3 books: genesis/exodus/matthew, book_count=3):

  • Positive path: schema_validator + build + validate_sqlite all pass.
  • Negative path: set book_count=99, confirmed both schema_validator and validate_sqlite emit book_count=99 listed=3 failures.

Final committed state (empty array):

  • python _tools/schema_validator.py136483 passed, 77 failed (same pre-existing set as master), 0 new failures ✅
  • python _tools/build_sqlite.pycanon_traditions: 0 rows
  • python _tools/validate_sqlite.py94 passed, 0 failed, 2 warnings ✅

Out of scope

Rollback

Revert this PR. Table is recreated from schema on each build so no migration cleanup.


Generated by Claude Code

Introduces the canon_traditions schema for the four major canonical
traditions (Protestant, Catholic, Eastern Orthodox, Ethiopian
Tewahedo) feeding the Canon Comparison screen. Seeds
content/meta/canon_traditions.json as an empty array; the four
seeded traditions land in HWGTB-P1-05.
schema_validator.py enforces id shape, required keys, and a
book_count-vs-canon_list consistency check. Books outside the 66-book
Protestant biblical canon are tolerated (deuterocanon / pseudepigrapha
will live there) provided they are snake_case ids. validate_sqlite.py
asserts the DB-side book_count invariant.
Closes#1539https://claude.ai/code/session_01PHELDhvq1dxY36oL5Gguad
@github-actions

Copy link
Copy Markdown

Content Pipeline Results

✅ All pipeline checks passed

StepStatusDetails
Schema Validation136483 passed, 77 failed
Build DB
DB Integrity94 passed, 0 failed

Content Pipeline — Quality & Accuracy Report

All content checks passed

Scope: 0 chapter(s) across 0 book(s)


Generated by ci_content_check.py

@github-actions

Copy link
Copy Markdown

Test Results

✅ All tests passed

PassedFailedTotal
Tests✅ 3474❌ 03474
Suites✅ 469❌ 0469

Coverage

StatementsBranchesFunctionsLines

⏱️ Duration: 82.4s

@CraigBuckmaster

Copy link
Copy Markdown
OwnerAuthor

Closing as superseded by #1590.

Both PRs modify the same _tools/build_sqlite_*.py schema files plus content/meta/canon_traditions.json — this PR seeds canon_traditions as an empty array and #1590 seeds it with the full 4 entries. #1590 contains the strict superset of this PR's diff.

Keeping #1590 and closing here to avoid a merge conflict on the schema files.

@CraigBuckmaster
CraigBuckmaster deleted the feature/hwgtb-p1-02-canon-traditions-schema branch April 23, 2026 20:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[HWGTB-P1-02] Schema: canon_traditions meta table

2 participants

@CraigBuckmaster@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add canon_traditions meta table + validator (#1539) - #1587

Closed
CraigBuckmaster wants to merge 1 commit into
masterfrom
feature/hwgtb-p1-02-canon-traditions-schema
Closed

feat: add canon_traditions meta table + validator (#1539)#1587
CraigBuckmaster wants to merge 1 commit into
masterfrom
feature/hwgtb-p1-02-canon-traditions-schema

Conversation

@CraigBuckmaster

Copy link
Copy Markdown
Owner

What this does

Introduces the canon_traditions meta table — schema for the four major canonical traditions (Protestant, Catholic, Eastern Orthodox, Ethiopian Tewahedo). Seeds content/meta/canon_traditions.json as an empty array; the four seeded entries land in HWGTB-P1-05 (#1542).

Closes

Closes#1539

Changes

  • New filecontent/meta/canon_traditions.json — empty array.
  • _tools/build_sqlite_schema.pyCREATE TABLE canon_traditions + idx_canon_traditions_sort.
  • _tools/build_sqlite_loaders.pypopulate_canon_traditions() loader.
  • _tools/build_sqlite.py — loader imported + registered in pipeline.
  • _tools/schema_validator.py — new CANON TRADITIONS section:
    • Required keys: id, label, book_count, canon_list
    • id is snake_case and unique
    • book_count equals the total canon_list[].books[] length
    • canon_list[].books[] validated per the issue. Books outside books.json (deuterocanon, pseudepigrapha, etc.) are tolerated with an informational log — they're expected for non-Protestant traditions — provided they pass the snake_case id shape.
  • _tools/validate_sqlite.py — DB-side book_count vs canon_list_json consistency check.
  • app/assets/db-manifest.json — content hash bump.

How I verified

Smoke test with a dummy tradition (3 books: genesis/exodus/matthew, book_count=3):

  • Positive path: schema_validator + build + validate_sqlite all pass.
  • Negative path: set book_count=99, confirmed both schema_validator and validate_sqlite emit book_count=99 listed=3 failures.

Final committed state (empty array):

  • python _tools/schema_validator.py136483 passed, 77 failed (same pre-existing set as master), 0 new failures ✅
  • python _tools/build_sqlite.pycanon_traditions: 0 rows
  • python _tools/validate_sqlite.py94 passed, 0 failed, 2 warnings ✅

Out of scope

Rollback

Revert this PR. Table is recreated from schema on each build so no migration cleanup.


Generated by Claude Code

Introduces the canon_traditions schema for the four major canonical
traditions (Protestant, Catholic, Eastern Orthodox, Ethiopian
Tewahedo) feeding the Canon Comparison screen. Seeds
content/meta/canon_traditions.json as an empty array; the four
seeded traditions land in HWGTB-P1-05.
schema_validator.py enforces id shape, required keys, and a
book_count-vs-canon_list consistency check. Books outside the 66-book
Protestant biblical canon are tolerated (deuterocanon / pseudepigrapha
will live there) provided they are snake_case ids. validate_sqlite.py
asserts the DB-side book_count invariant.
Closes#1539https://claude.ai/code/session_01PHELDhvq1dxY36oL5Gguad
@github-actions

Copy link
Copy Markdown

Content Pipeline Results

✅ All pipeline checks passed

StepStatusDetails
Schema Validation136483 passed, 77 failed
Build DB
DB Integrity94 passed, 0 failed

Content Pipeline — Quality & Accuracy Report

All content checks passed

Scope: 0 chapter(s) across 0 book(s)


Generated by ci_content_check.py

@github-actions

Copy link
Copy Markdown

Test Results

✅ All tests passed

PassedFailedTotal
Tests✅ 3474❌ 03474
Suites✅ 469❌ 0469

Coverage

StatementsBranchesFunctionsLines

⏱️ Duration: 82.4s

@CraigBuckmaster

Copy link
Copy Markdown
OwnerAuthor

Closing as superseded by #1590.

Both PRs modify the same _tools/build_sqlite_*.py schema files plus content/meta/canon_traditions.json — this PR seeds canon_traditions as an empty array and #1590 seeds it with the full 4 entries. #1590 contains the strict superset of this PR's diff.

Keeping #1590 and closing here to avoid a merge conflict on the schema files.

@CraigBuckmaster
CraigBuckmaster deleted the feature/hwgtb-p1-02-canon-traditions-schema branch April 23, 2026 20:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[HWGTB-P1-02] Schema: canon_traditions meta table

2 participants

@CraigBuckmaster@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: add canon_traditions meta table + validator (#1539) - #1587

Closed
CraigBuckmaster wants to merge 1 commit into
masterfrom
feature/hwgtb-p1-02-canon-traditions-schema
Closed

feat: add canon_traditions meta table + validator (#1539)#1587
CraigBuckmaster wants to merge 1 commit into
masterfrom
feature/hwgtb-p1-02-canon-traditions-schema

Conversation

@CraigBuckmaster

Copy link
Copy Markdown
Owner

What this does

Introduces the canon_traditions meta table — schema for the four major canonical traditions (Protestant, Catholic, Eastern Orthodox, Ethiopian Tewahedo). Seeds content/meta/canon_traditions.json as an empty array; the four seeded entries land in HWGTB-P1-05 (#1542).

Closes

Closes#1539

Changes

  • New filecontent/meta/canon_traditions.json — empty array.
  • _tools/build_sqlite_schema.pyCREATE TABLE canon_traditions + idx_canon_traditions_sort.
  • _tools/build_sqlite_loaders.pypopulate_canon_traditions() loader.
  • _tools/build_sqlite.py — loader imported + registered in pipeline.
  • _tools/schema_validator.py — new CANON TRADITIONS section:
    • Required keys: id, label, book_count, canon_list
    • id is snake_case and unique
    • book_count equals the total canon_list[].books[] length
    • canon_list[].books[] validated per the issue. Books outside books.json (deuterocanon, pseudepigrapha, etc.) are tolerated with an informational log — they're expected for non-Protestant traditions — provided they pass the snake_case id shape.
  • _tools/validate_sqlite.py — DB-side book_count vs canon_list_json consistency check.
  • app/assets/db-manifest.json — content hash bump.

How I verified

Smoke test with a dummy tradition (3 books: genesis/exodus/matthew, book_count=3):

  • Positive path: schema_validator + build + validate_sqlite all pass.
  • Negative path: set book_count=99, confirmed both schema_validator and validate_sqlite emit book_count=99 listed=3 failures.

Final committed state (empty array):

  • python _tools/schema_validator.py136483 passed, 77 failed (same pre-existing set as master), 0 new failures ✅
  • python _tools/build_sqlite.pycanon_traditions: 0 rows
  • python _tools/validate_sqlite.py94 passed, 0 failed, 2 warnings ✅

Out of scope

Rollback

Revert this PR. Table is recreated from schema on each build so no migration cleanup.


Generated by Claude Code

Introduces the canon_traditions schema for the four major canonical
traditions (Protestant, Catholic, Eastern Orthodox, Ethiopian
Tewahedo) feeding the Canon Comparison screen. Seeds
content/meta/canon_traditions.json as an empty array; the four
seeded traditions land in HWGTB-P1-05.
schema_validator.py enforces id shape, required keys, and a
book_count-vs-canon_list consistency check. Books outside the 66-book
Protestant biblical canon are tolerated (deuterocanon / pseudepigrapha
will live there) provided they are snake_case ids. validate_sqlite.py
asserts the DB-side book_count invariant.
Closes#1539https://claude.ai/code/session_01PHELDhvq1dxY36oL5Gguad
@github-actions

Copy link
Copy Markdown

Content Pipeline Results

✅ All pipeline checks passed

StepStatusDetails
Schema Validation136483 passed, 77 failed
Build DB
DB Integrity94 passed, 0 failed

Content Pipeline — Quality & Accuracy Report

All content checks passed

Scope: 0 chapter(s) across 0 book(s)


Generated by ci_content_check.py

@github-actions

Copy link
Copy Markdown

Test Results

✅ All tests passed

PassedFailedTotal
Tests✅ 3474❌ 03474
Suites✅ 469❌ 0469

Coverage

StatementsBranchesFunctionsLines

⏱️ Duration: 82.4s

@CraigBuckmaster

Copy link
Copy Markdown
OwnerAuthor

Closing as superseded by #1590.

Both PRs modify the same _tools/build_sqlite_*.py schema files plus content/meta/canon_traditions.json — this PR seeds canon_traditions as an empty array and #1590 seeds it with the full 4 entries. #1590 contains the strict superset of this PR's diff.

Keeping #1590 and closing here to avoid a merge conflict on the schema files.

@CraigBuckmaster
CraigBuckmaster deleted the feature/hwgtb-p1-02-canon-traditions-schema branch April 23, 2026 20:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[HWGTB-P1-02] Schema: canon_traditions meta table

2 participants

@CraigBuckmaster@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add canon_traditions meta table + validator (#1539) - #1587

Closed
CraigBuckmaster wants to merge 1 commit into
masterfrom
feature/hwgtb-p1-02-canon-traditions-schema
Closed

feat: add canon_traditions meta table + validator (#1539)#1587
CraigBuckmaster wants to merge 1 commit into
masterfrom
feature/hwgtb-p1-02-canon-traditions-schema

Conversation

@CraigBuckmaster

Copy link
Copy Markdown
Owner

What this does

Introduces the canon_traditions meta table — schema for the four major canonical traditions (Protestant, Catholic, Eastern Orthodox, Ethiopian Tewahedo). Seeds content/meta/canon_traditions.json as an empty array; the four seeded entries land in HWGTB-P1-05 (#1542).

Closes

Closes#1539

Changes

  • New filecontent/meta/canon_traditions.json — empty array.
  • _tools/build_sqlite_schema.pyCREATE TABLE canon_traditions + idx_canon_traditions_sort.
  • _tools/build_sqlite_loaders.pypopulate_canon_traditions() loader.
  • _tools/build_sqlite.py — loader imported + registered in pipeline.
  • _tools/schema_validator.py — new CANON TRADITIONS section:
    • Required keys: id, label, book_count, canon_list
    • id is snake_case and unique
    • book_count equals the total canon_list[].books[] length
    • canon_list[].books[] validated per the issue. Books outside books.json (deuterocanon, pseudepigrapha, etc.) are tolerated with an informational log — they're expected for non-Protestant traditions — provided they pass the snake_case id shape.
  • _tools/validate_sqlite.py — DB-side book_count vs canon_list_json consistency check.
  • app/assets/db-manifest.json — content hash bump.

How I verified

Smoke test with a dummy tradition (3 books: genesis/exodus/matthew, book_count=3):

  • Positive path: schema_validator + build + validate_sqlite all pass.
  • Negative path: set book_count=99, confirmed both schema_validator and validate_sqlite emit book_count=99 listed=3 failures.

Final committed state (empty array):

  • python _tools/schema_validator.py136483 passed, 77 failed (same pre-existing set as master), 0 new failures ✅
  • python _tools/build_sqlite.pycanon_traditions: 0 rows
  • python _tools/validate_sqlite.py94 passed, 0 failed, 2 warnings ✅

Out of scope

Rollback

Revert this PR. Table is recreated from schema on each build so no migration cleanup.


Generated by Claude Code

Introduces the canon_traditions schema for the four major canonical
traditions (Protestant, Catholic, Eastern Orthodox, Ethiopian
Tewahedo) feeding the Canon Comparison screen. Seeds
content/meta/canon_traditions.json as an empty array; the four
seeded traditions land in HWGTB-P1-05.
schema_validator.py enforces id shape, required keys, and a
book_count-vs-canon_list consistency check. Books outside the 66-book
Protestant biblical canon are tolerated (deuterocanon / pseudepigrapha
will live there) provided they are snake_case ids. validate_sqlite.py
asserts the DB-side book_count invariant.
Closes#1539https://claude.ai/code/session_01PHELDhvq1dxY36oL5Gguad
@github-actions

Copy link
Copy Markdown

Content Pipeline Results

✅ All pipeline checks passed

StepStatusDetails
Schema Validation136483 passed, 77 failed
Build DB
DB Integrity94 passed, 0 failed

Content Pipeline — Quality & Accuracy Report

All content checks passed

Scope: 0 chapter(s) across 0 book(s)


Generated by ci_content_check.py

@github-actions

Copy link
Copy Markdown

Test Results

✅ All tests passed

PassedFailedTotal
Tests✅ 3474❌ 03474
Suites✅ 469❌ 0469

Coverage

StatementsBranchesFunctionsLines

⏱️ Duration: 82.4s

@CraigBuckmaster

Copy link
Copy Markdown
OwnerAuthor

Closing as superseded by #1590.

Both PRs modify the same _tools/build_sqlite_*.py schema files plus content/meta/canon_traditions.json — this PR seeds canon_traditions as an empty array and #1590 seeds it with the full 4 entries. #1590 contains the strict superset of this PR's diff.

Keeping #1590 and closing here to avoid a merge conflict on the schema files.

@CraigBuckmaster
CraigBuckmaster deleted the feature/hwgtb-p1-02-canon-traditions-schema branch April 23, 2026 20:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[HWGTB-P1-02] Schema: canon_traditions meta table

2 participants

@CraigBuckmaster@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add canon_traditions meta table + validator (#1539) - #1587

Closed
CraigBuckmaster wants to merge 1 commit into
masterfrom
feature/hwgtb-p1-02-canon-traditions-schema
Closed

feat: add canon_traditions meta table + validator (#1539)#1587
CraigBuckmaster wants to merge 1 commit into
masterfrom
feature/hwgtb-p1-02-canon-traditions-schema

Conversation

@CraigBuckmaster

Copy link
Copy Markdown
Owner

What this does

Introduces the canon_traditions meta table — schema for the four major canonical traditions (Protestant, Catholic, Eastern Orthodox, Ethiopian Tewahedo). Seeds content/meta/canon_traditions.json as an empty array; the four seeded entries land in HWGTB-P1-05 (#1542).

Closes

Closes#1539

Changes

  • New filecontent/meta/canon_traditions.json — empty array.
  • _tools/build_sqlite_schema.pyCREATE TABLE canon_traditions + idx_canon_traditions_sort.
  • _tools/build_sqlite_loaders.pypopulate_canon_traditions() loader.
  • _tools/build_sqlite.py — loader imported + registered in pipeline.
  • _tools/schema_validator.py — new CANON TRADITIONS section:
    • Required keys: id, label, book_count, canon_list
    • id is snake_case and unique
    • book_count equals the total canon_list[].books[] length
    • canon_list[].books[] validated per the issue. Books outside books.json (deuterocanon, pseudepigrapha, etc.) are tolerated with an informational log — they're expected for non-Protestant traditions — provided they pass the snake_case id shape.
  • _tools/validate_sqlite.py — DB-side book_count vs canon_list_json consistency check.
  • app/assets/db-manifest.json — content hash bump.

How I verified

Smoke test with a dummy tradition (3 books: genesis/exodus/matthew, book_count=3):

  • Positive path: schema_validator + build + validate_sqlite all pass.
  • Negative path: set book_count=99, confirmed both schema_validator and validate_sqlite emit book_count=99 listed=3 failures.

Final committed state (empty array):

  • python _tools/schema_validator.py136483 passed, 77 failed (same pre-existing set as master), 0 new failures ✅
  • python _tools/build_sqlite.pycanon_traditions: 0 rows
  • python _tools/validate_sqlite.py94 passed, 0 failed, 2 warnings ✅

Out of scope

Rollback

Revert this PR. Table is recreated from schema on each build so no migration cleanup.


Generated by Claude Code

Introduces the canon_traditions schema for the four major canonical
traditions (Protestant, Catholic, Eastern Orthodox, Ethiopian
Tewahedo) feeding the Canon Comparison screen. Seeds
content/meta/canon_traditions.json as an empty array; the four
seeded traditions land in HWGTB-P1-05.
schema_validator.py enforces id shape, required keys, and a
book_count-vs-canon_list consistency check. Books outside the 66-book
Protestant biblical canon are tolerated (deuterocanon / pseudepigrapha
will live there) provided they are snake_case ids. validate_sqlite.py
asserts the DB-side book_count invariant.
Closes#1539https://claude.ai/code/session_01PHELDhvq1dxY36oL5Gguad
@github-actions

Copy link
Copy Markdown

Content Pipeline Results

✅ All pipeline checks passed

StepStatusDetails
Schema Validation136483 passed, 77 failed
Build DB
DB Integrity94 passed, 0 failed

Content Pipeline — Quality & Accuracy Report

All content checks passed

Scope: 0 chapter(s) across 0 book(s)


Generated by ci_content_check.py

@github-actions

Copy link
Copy Markdown

Test Results

✅ All tests passed

PassedFailedTotal
Tests✅ 3474❌ 03474
Suites✅ 469❌ 0469

Coverage

StatementsBranchesFunctionsLines

⏱️ Duration: 82.4s

@CraigBuckmaster

Copy link
Copy Markdown
OwnerAuthor

Closing as superseded by #1590.

Both PRs modify the same _tools/build_sqlite_*.py schema files plus content/meta/canon_traditions.json — this PR seeds canon_traditions as an empty array and #1590 seeds it with the full 4 entries. #1590 contains the strict superset of this PR's diff.

Keeping #1590 and closing here to avoid a merge conflict on the schema files.

@CraigBuckmaster
CraigBuckmaster deleted the feature/hwgtb-p1-02-canon-traditions-schema branch April 23, 2026 20:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[HWGTB-P1-02] Schema: canon_traditions meta table

2 participants

@CraigBuckmaster@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: add canon_traditions meta table + validator (#1539) - #1587

Closed
CraigBuckmaster wants to merge 1 commit into
masterfrom
feature/hwgtb-p1-02-canon-traditions-schema
Closed

feat: add canon_traditions meta table + validator (#1539)#1587
CraigBuckmaster wants to merge 1 commit into
masterfrom
feature/hwgtb-p1-02-canon-traditions-schema

Conversation

@CraigBuckmaster

Copy link
Copy Markdown
Owner

What this does

Introduces the canon_traditions meta table — schema for the four major canonical traditions (Protestant, Catholic, Eastern Orthodox, Ethiopian Tewahedo). Seeds content/meta/canon_traditions.json as an empty array; the four seeded entries land in HWGTB-P1-05 (#1542).

Closes

Closes#1539

Changes

  • New filecontent/meta/canon_traditions.json — empty array.
  • _tools/build_sqlite_schema.pyCREATE TABLE canon_traditions + idx_canon_traditions_sort.
  • _tools/build_sqlite_loaders.pypopulate_canon_traditions() loader.
  • _tools/build_sqlite.py — loader imported + registered in pipeline.
  • _tools/schema_validator.py — new CANON TRADITIONS section:
    • Required keys: id, label, book_count, canon_list
    • id is snake_case and unique
    • book_count equals the total canon_list[].books[] length
    • canon_list[].books[] validated per the issue. Books outside books.json (deuterocanon, pseudepigrapha, etc.) are tolerated with an informational log — they're expected for non-Protestant traditions — provided they pass the snake_case id shape.
  • _tools/validate_sqlite.py — DB-side book_count vs canon_list_json consistency check.
  • app/assets/db-manifest.json — content hash bump.

How I verified

Smoke test with a dummy tradition (3 books: genesis/exodus/matthew, book_count=3):

  • Positive path: schema_validator + build + validate_sqlite all pass.
  • Negative path: set book_count=99, confirmed both schema_validator and validate_sqlite emit book_count=99 listed=3 failures.

Final committed state (empty array):

  • python _tools/schema_validator.py136483 passed, 77 failed (same pre-existing set as master), 0 new failures ✅
  • python _tools/build_sqlite.pycanon_traditions: 0 rows
  • python _tools/validate_sqlite.py94 passed, 0 failed, 2 warnings ✅

Out of scope

Rollback

Revert this PR. Table is recreated from schema on each build so no migration cleanup.


Generated by Claude Code

Introduces the canon_traditions schema for the four major canonical
traditions (Protestant, Catholic, Eastern Orthodox, Ethiopian
Tewahedo) feeding the Canon Comparison screen. Seeds
content/meta/canon_traditions.json as an empty array; the four
seeded traditions land in HWGTB-P1-05.
schema_validator.py enforces id shape, required keys, and a
book_count-vs-canon_list consistency check. Books outside the 66-book
Protestant biblical canon are tolerated (deuterocanon / pseudepigrapha
will live there) provided they are snake_case ids. validate_sqlite.py
asserts the DB-side book_count invariant.
Closes#1539https://claude.ai/code/session_01PHELDhvq1dxY36oL5Gguad
@github-actions

Copy link
Copy Markdown

Content Pipeline Results

✅ All pipeline checks passed

StepStatusDetails
Schema Validation136483 passed, 77 failed
Build DB
DB Integrity94 passed, 0 failed

Content Pipeline — Quality & Accuracy Report

All content checks passed

Scope: 0 chapter(s) across 0 book(s)


Generated by ci_content_check.py

@github-actions

Copy link
Copy Markdown

Test Results

✅ All tests passed

PassedFailedTotal
Tests✅ 3474❌ 03474
Suites✅ 469❌ 0469

Coverage

StatementsBranchesFunctionsLines

⏱️ Duration: 82.4s

@CraigBuckmaster

Copy link
Copy Markdown
OwnerAuthor

Closing as superseded by #1590.

Both PRs modify the same _tools/build_sqlite_*.py schema files plus content/meta/canon_traditions.json — this PR seeds canon_traditions as an empty array and #1590 seeds it with the full 4 entries. #1590 contains the strict superset of this PR's diff.

Keeping #1590 and closing here to avoid a merge conflict on the schema files.

@CraigBuckmaster
CraigBuckmaster deleted the feature/hwgtb-p1-02-canon-traditions-schema branch April 23, 2026 20:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[HWGTB-P1-02] Schema: canon_traditions meta table

2 participants

@CraigBuckmaster@claude