Refresh project statistics and source audit
Browse files- README.md +5 -1
- data/resource_source_audit.csv +0 -0
- data/resources.csv +0 -0
- data/resources.jsonl +0 -0
- data/resources.parquet +2 -2
- design-qa.md +2 -2
- docs/assets/resources.json +0 -0
- docs/index.html +1 -1
- meta/DISTRIBUTION.md +9 -9
- meta/hf_card_body.md +4 -0
- scripts/build_hf_card.py +12 -0
- scripts/check_project_consistency.py +51 -4
README.md
CHANGED
|
@@ -57,11 +57,15 @@ Current release: **v0.9.0**
|
|
| 57 |
| Surface | Count |
|
| 58 |
| --- | ---: |
|
| 59 |
| Resources | 601 |
|
|
|
|
|
|
|
| 60 |
| Operational patterns | 20 |
|
| 61 |
| Adaptable loop contracts | 20 |
|
| 62 |
| Runtime starters | 8 |
|
|
|
|
|
|
|
| 63 |
|
| 64 |
-
At the **2026-07-20** source check, **
|
| 65 |
|
| 66 |
## What A Loop Contract Is
|
| 67 |
|
|
|
|
| 57 |
| Surface | Count |
|
| 58 |
| --- | ---: |
|
| 59 |
| Resources | 601 |
|
| 60 |
+
| Research papers | 220 |
|
| 61 |
+
| Model-layer resources | 29 |
|
| 62 |
| Operational patterns | 20 |
|
| 63 |
| Adaptable loop contracts | 20 |
|
| 64 |
| Runtime starters | 8 |
|
| 65 |
+
| Dataset fields | 50 |
|
| 66 |
+
| Language entry points | 8 |
|
| 67 |
|
| 68 |
+
At the **2026-07-20** source check, **548 public links opened successfully**, **5 required access**, **48 pointed to repository files**, and **0 were broken or unreachable**.
|
| 69 |
|
| 70 |
## What A Loop Contract Is
|
| 71 |
|
data/resource_source_audit.csv
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/resources.csv
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/resources.jsonl
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/resources.parquet
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f58ce5585120e05a2d87f3d36cf94e83d933df69bf51a295d9e587bd9f270d7f
|
| 3 |
+
size 497218
|
design-qa.md
CHANGED
|
@@ -78,7 +78,7 @@
|
|
| 78 |
- Mobile navigation: opens all nine project links, reports `aria-expanded="true"`, closes on Escape, and restores focus to the menu button.
|
| 79 |
- Pattern filter: `accessibility` returns exactly one of the 20 patterns.
|
| 80 |
- Resource Atlas: remains idle above the fold, loads on approach or a direct resource anchor, and reports `601 of 601 resources | showing 8` on a fresh mobile load.
|
| 81 |
-
- Resource interactions: the Model loop-layer filter returns
|
| 82 |
- Resource row schema: desktop exposes Work, Year, Published at, and Evidence; mobile stacks the same labels. A `ReasoningBank` query returns one row with its ICLR venue, arXiv identifier, Tier A evidence, task fit, and source record without horizontal overflow.
|
| 83 |
- Scene motion: the canvas frame counter advanced from 640 to 662 over 900 ms. Two canvas crops taken 1.2 seconds apart changed 17.79% of sampled RGB channels.
|
| 84 |
- Scene pixels: the current desktop canvas has 7,062 colors with RGB standard deviations of 35.93, 29.76, and 22.29; mobile has 5,755 colors with deviations of 40.73, 30.54, and 19.70. Both renders are nonblank and well contrasted.
|
|
@@ -86,7 +86,7 @@
|
|
| 86 |
- Future directions: direct-anchor restoration waits for the Resource Atlas reflow, all three audience tracks remain readable, and the agenda CTA is fully visible at desktop and mobile widths.
|
| 87 |
- Console: no page-origin errors or warnings during mobile navigation, pattern filtering, and Resource Atlas interactions.
|
| 88 |
- Narrow phone: 320 x 844, document width equals viewport width; the headline stays within 16 px gutters and the Three.js canvas remains fully inside the 288 px content width.
|
| 89 |
-
- Source audit: 601 rows checked;
|
| 90 |
- Data and copy: the website, README, translations, social preview source, release copy, and Hugging Face card all report 601 resources, 20 patterns, 20 contracts, 8 runtime starters, and version 0.9.0. The dataset exposes 50 fields, including `loop_layer` and `scope_fit`.
|
| 91 |
- Semantic scene pass: the desktop hero crop paints 14.61% of pixels beyond the paper background with a 254.71 luminance range; the desktop stack paints 27.83% with a 249.98 range; the mobile hero paints 20.84% with a 229.45 range.
|
| 92 |
- Stage interaction: selecting Verify updates `aria-pressed` across all six controls and replaces the live detail with the independent evidence-gate explanation.
|
|
|
|
| 78 |
- Mobile navigation: opens all nine project links, reports `aria-expanded="true"`, closes on Escape, and restores focus to the menu button.
|
| 79 |
- Pattern filter: `accessibility` returns exactly one of the 20 patterns.
|
| 80 |
- Resource Atlas: remains idle above the fold, loads on approach or a direct resource anchor, and reports `601 of 601 resources | showing 8` on a fresh mobile load.
|
| 81 |
+
- Resource interactions: the Model loop-layer filter returns 29 of 601 resources (28 papers plus Awesome Loop Models), paginates eight at a time on mobile, and renders Loopie and LoopWM with their 2026 arXiv records and adjacent-scope labels.
|
| 82 |
- Resource row schema: desktop exposes Work, Year, Published at, and Evidence; mobile stacks the same labels. A `ReasoningBank` query returns one row with its ICLR venue, arXiv identifier, Tier A evidence, task fit, and source record without horizontal overflow.
|
| 83 |
- Scene motion: the canvas frame counter advanced from 640 to 662 over 900 ms. Two canvas crops taken 1.2 seconds apart changed 17.79% of sampled RGB channels.
|
| 84 |
- Scene pixels: the current desktop canvas has 7,062 colors with RGB standard deviations of 35.93, 29.76, and 22.29; mobile has 5,755 colors with deviations of 40.73, 30.54, and 19.70. Both renders are nonblank and well contrasted.
|
|
|
|
| 86 |
- Future directions: direct-anchor restoration waits for the Resource Atlas reflow, all three audience tracks remain readable, and the agenda CTA is fully visible at desktop and mobile widths.
|
| 87 |
- Console: no page-origin errors or warnings during mobile navigation, pattern filtering, and Resource Atlas interactions.
|
| 88 |
- Narrow phone: 320 x 844, document width equals viewport width; the headline stays within 16 px gutters and the Three.js canvas remains fully inside the 288 px content width.
|
| 89 |
+
- Source audit: 601 rows checked; 548 public sources reachable, 5 access-restricted, 48 repository-native, and 0 broken or unreachable as of 2026-07-20 UTC.
|
| 90 |
- Data and copy: the website, README, translations, social preview source, release copy, and Hugging Face card all report 601 resources, 20 patterns, 20 contracts, 8 runtime starters, and version 0.9.0. The dataset exposes 50 fields, including `loop_layer` and `scope_fit`.
|
| 91 |
- Semantic scene pass: the desktop hero crop paints 14.61% of pixels beyond the paper background with a 254.71 luminance range; the desktop stack paints 27.83% with a 249.98 range; the mobile hero paints 20.84% with a 229.45 range.
|
| 92 |
- Stage interaction: selecting Verify updates `aria-pressed` across all six controls and replaces the live detail with the independent evidence-gate explanation.
|
docs/assets/resources.json
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
docs/index.html
CHANGED
|
@@ -1770,7 +1770,7 @@
|
|
| 1770 |
</div>
|
| 1771 |
<p class="section-intro">Filter 601 resources by goal, loop layer, lifecycle, artifact type, and evidence class. Open any result to see its contribution, novelty, impact, scope, publication details, and original source.</p>
|
| 1772 |
</div>
|
| 1773 |
-
<p class="audit-note"><strong>Last source check, 2026-07-20 UTC:</strong>
|
| 1774 |
<div class="loop-layer-map" aria-label="Where different loop concepts live">
|
| 1775 |
<div class="loop-layer-item"><span>Inner loop</span><strong>Model recurrence</strong><p>A learned block refines hidden or latent state inside one inference. Included as an adjacent foundation.</p></div>
|
| 1776 |
<div class="loop-layer-item"><span>Task loop</span><strong>Agent execution</strong><p>The model reasons, calls tools, observes results, and updates working state while solving one task.</p></div>
|
|
|
|
| 1770 |
</div>
|
| 1771 |
<p class="section-intro">Filter 601 resources by goal, loop layer, lifecycle, artifact type, and evidence class. Open any result to see its contribution, novelty, impact, scope, publication details, and original source.</p>
|
| 1772 |
</div>
|
| 1773 |
+
<p class="audit-note"><strong>Last source check, 2026-07-20 UTC:</strong> 548 public links opened successfully, 5 required access, 48 point to files in this repository, and none were broken or unreachable. <a href="https://github.com/ChaoYue0307/awesome-loop-engineering/blob/main/data/resource_source_audit.csv">View the results</a> or <a href="https://github.com/ChaoYue0307/awesome-loop-engineering/issues/new?template=annotation-correction.yml">report a correction</a>.</p>
|
| 1774 |
<div class="loop-layer-map" aria-label="Where different loop concepts live">
|
| 1775 |
<div class="loop-layer-item"><span>Inner loop</span><strong>Model recurrence</strong><p>A learned block refines hidden or latent state inside one inference. Included as an adjacent foundation.</p></div>
|
| 1776 |
<div class="loop-layer-item"><span>Task loop</span><strong>Agent execution</strong><p>The model reasons, calls tools, observes results, and updates working state while solving one task.</p></div>
|
meta/DISTRIBUTION.md
CHANGED
|
@@ -60,21 +60,21 @@ Do not use reciprocal-star requests, broad promotional pull requests, or unrelat
|
|
| 60 |
|
| 61 |
GitHub retains repository traffic details for only 14 days. Record a snapshot weekly, using the same definitions each time.
|
| 62 |
|
| 63 |
-
Snapshot captured on 2026-07-
|
| 64 |
|
| 65 |
| Metric | Baseline |
|
| 66 |
| --- | ---: |
|
| 67 |
-
| Repository views |
|
| 68 |
-
| Unique visitors |
|
| 69 |
-
| Clones |
|
| 70 |
-
| Unique cloners |
|
| 71 |
-
| Stars |
|
| 72 |
-
| Forks |
|
| 73 |
| Watchers | 1 |
|
| 74 |
|
| 75 |
-
The repository overview reached
|
| 76 |
|
| 77 |
-
Since the previous snapshot, stars increased from
|
| 78 |
|
| 79 |
Working 30-day campaign targets:
|
| 80 |
|
|
|
|
| 60 |
|
| 61 |
GitHub retains repository traffic details for only 14 days. Record a snapshot weekly, using the same definitions each time.
|
| 62 |
|
| 63 |
+
Snapshot captured on 2026-07-20 for the API window ending 2026-07-19:
|
| 64 |
|
| 65 |
| Metric | Baseline |
|
| 66 |
| --- | ---: |
|
| 67 |
+
| Repository views | 637 |
|
| 68 |
+
| Unique visitors | 157 |
|
| 69 |
+
| Clones | 720 |
|
| 70 |
+
| Unique cloners | 199 |
|
| 71 |
+
| Stars | 35 |
|
| 72 |
+
| Forks | 7 |
|
| 73 |
| Watchers | 1 |
|
| 74 |
|
| 75 |
+
The repository overview reached 126 unique visitors. The Chinese README remained the second-most visited content path with 20 unique visitors. The largest identifiable referrers were GitHub and Google (22 unique visitors each), Bing (11), and the project site (8); X contributed two identifiable visitors. Clone traffic remains unusually high and may include automated clients, so do not treat clone counts as human adoption without corroborating forks or contributions.
|
| 76 |
|
| 77 |
+
Since the previous snapshot, stars increased from 31 to 35 and forks from 6 to 7 while watchers remained at 1. Qualified discovery is improving, but release and discussion subscriptions remain the clearest gap; the next campaign should keep prioritizing useful external reach and the low-noise release/digest path.
|
| 78 |
|
| 79 |
Working 30-day campaign targets:
|
| 80 |
|
meta/hf_card_body.md
CHANGED
|
@@ -24,9 +24,13 @@ Current release: **v{{VERSION}}**
|
|
| 24 |
| Surface | Count |
|
| 25 |
| --- | ---: |
|
| 26 |
| Resources | {{RESOURCE_COUNT}} |
|
|
|
|
|
|
|
| 27 |
| Operational patterns | {{PATTERN_COUNT}} |
|
| 28 |
| Adaptable loop contracts | {{CONTRACT_COUNT}} |
|
| 29 |
| Runtime starters | {{RUNNABLE_COUNT}} |
|
|
|
|
|
|
|
| 30 |
|
| 31 |
At the **{{AUDIT_DATE}}** source check, **{{REACHABLE_COUNT}} public links opened successfully**, **{{RESTRICTED_COUNT}} required access**, **{{LOCAL_COUNT}} pointed to repository files**, and **{{BROKEN_COUNT}} were broken or unreachable**.
|
| 32 |
|
|
|
|
| 24 |
| Surface | Count |
|
| 25 |
| --- | ---: |
|
| 26 |
| Resources | {{RESOURCE_COUNT}} |
|
| 27 |
+
| Research papers | {{PAPER_COUNT}} |
|
| 28 |
+
| Model-layer resources | {{MODEL_COUNT}} |
|
| 29 |
| Operational patterns | {{PATTERN_COUNT}} |
|
| 30 |
| Adaptable loop contracts | {{CONTRACT_COUNT}} |
|
| 31 |
| Runtime starters | {{RUNNABLE_COUNT}} |
|
| 32 |
+
| Dataset fields | {{FIELD_COUNT}} |
|
| 33 |
+
| Language entry points | {{LANGUAGE_COUNT}} |
|
| 34 |
|
| 35 |
At the **{{AUDIT_DATE}}** source check, **{{REACHABLE_COUNT}} public links opened successfully**, **{{RESTRICTED_COUNT}} required access**, **{{LOCAL_COUNT}} pointed to repository files**, and **{{BROKEN_COUNT}} were broken or unreachable**.
|
| 36 |
|
scripts/build_hf_card.py
CHANGED
|
@@ -35,15 +35,24 @@ def load_rows() -> list[dict[str, str]]:
|
|
| 35 |
def project_context() -> dict[str, str]:
|
| 36 |
rows = load_rows()
|
| 37 |
statuses = Counter(row.get("source_status", "") for row in rows)
|
|
|
|
|
|
|
| 38 |
audit_dates = sorted({row.get("audited_at", "")[:10] for row in rows if row.get("audited_at")})
|
| 39 |
version_match = re.search(r"^version:\s*([^\s]+)\s*$", CITATION.read_text(encoding="utf-8"), re.MULTILINE)
|
| 40 |
|
| 41 |
patterns = [path for path in (ROOT / "patterns").glob("*.md") if path.name not in {"README.md", "MATRIX.md"}]
|
| 42 |
contracts = list((ROOT / "examples").glob("*-loop.json"))
|
| 43 |
runnable = [path for path in (ROOT / "examples" / "runnable").iterdir() if path.is_file() and path.name != "README.md"]
|
|
|
|
|
|
|
|
|
|
| 44 |
|
| 45 |
return {
|
| 46 |
"RESOURCE_COUNT": str(len(rows)),
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
"REACHABLE_COUNT": str(statuses["ok"]),
|
| 48 |
"RESTRICTED_COUNT": str(statuses["restricted"]),
|
| 49 |
"LOCAL_COUNT": str(statuses["local_ok"]),
|
|
@@ -52,6 +61,9 @@ def project_context() -> dict[str, str]:
|
|
| 52 |
"PATTERN_COUNT": str(len(patterns)),
|
| 53 |
"CONTRACT_COUNT": str(len(contracts)),
|
| 54 |
"RUNNABLE_COUNT": str(len(runnable)),
|
|
|
|
|
|
|
|
|
|
| 55 |
"VERSION": version_match.group(1) if version_match else "unversioned",
|
| 56 |
}
|
| 57 |
|
|
|
|
| 35 |
def project_context() -> dict[str, str]:
|
| 36 |
rows = load_rows()
|
| 37 |
statuses = Counter(row.get("source_status", "") for row in rows)
|
| 38 |
+
resource_types = Counter(row.get("resource_type", "") for row in rows)
|
| 39 |
+
loop_layers = Counter(row.get("loop_layer", "") for row in rows)
|
| 40 |
audit_dates = sorted({row.get("audited_at", "")[:10] for row in rows if row.get("audited_at")})
|
| 41 |
version_match = re.search(r"^version:\s*([^\s]+)\s*$", CITATION.read_text(encoding="utf-8"), re.MULTILINE)
|
| 42 |
|
| 43 |
patterns = [path for path in (ROOT / "patterns").glob("*.md") if path.name not in {"README.md", "MATRIX.md"}]
|
| 44 |
contracts = list((ROOT / "examples").glob("*-loop.json"))
|
| 45 |
runnable = [path for path in (ROOT / "examples" / "runnable").iterdir() if path.is_file() and path.name != "README.md"]
|
| 46 |
+
executable = [path for path in runnable if path.suffix != ".md"]
|
| 47 |
+
runtime_templates = [path for path in runnable if path.suffix == ".md"]
|
| 48 |
+
language_count = 1 + len(list(ROOT.glob("README.*.md")))
|
| 49 |
|
| 50 |
return {
|
| 51 |
"RESOURCE_COUNT": str(len(rows)),
|
| 52 |
+
"PAPER_COUNT": str(resource_types["Paper"]),
|
| 53 |
+
"MODEL_COUNT": str(loop_layers["model"]),
|
| 54 |
+
"MODEL_PAPER_COUNT": str(sum(row.get("loop_layer") == "model" and row.get("resource_type") == "Paper" for row in rows)),
|
| 55 |
+
"FIELD_COUNT": str(len(rows[0]) if rows else 0),
|
| 56 |
"REACHABLE_COUNT": str(statuses["ok"]),
|
| 57 |
"RESTRICTED_COUNT": str(statuses["restricted"]),
|
| 58 |
"LOCAL_COUNT": str(statuses["local_ok"]),
|
|
|
|
| 61 |
"PATTERN_COUNT": str(len(patterns)),
|
| 62 |
"CONTRACT_COUNT": str(len(contracts)),
|
| 63 |
"RUNNABLE_COUNT": str(len(runnable)),
|
| 64 |
+
"EXECUTABLE_COUNT": str(len(executable)),
|
| 65 |
+
"RUNTIME_TEMPLATE_COUNT": str(len(runtime_templates)),
|
| 66 |
+
"LANGUAGE_COUNT": str(language_count),
|
| 67 |
"VERSION": version_match.group(1) if version_match else "unversioned",
|
| 68 |
}
|
| 69 |
|
scripts/check_project_consistency.py
CHANGED
|
@@ -107,6 +107,11 @@ def main() -> int:
|
|
| 107 |
context = project_context()
|
| 108 |
count = context["RESOURCE_COUNT"]
|
| 109 |
version = context["VERSION"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
failures: list[str] = []
|
| 111 |
|
| 112 |
require(
|
|
@@ -114,7 +119,9 @@ def main() -> int:
|
|
| 114 |
[
|
| 115 |
f"resources-{count}-",
|
| 116 |
f"**{count} resources**",
|
| 117 |
-
|
|
|
|
|
|
|
| 118 |
],
|
| 119 |
failures,
|
| 120 |
)
|
|
@@ -124,14 +131,34 @@ def main() -> int:
|
|
| 124 |
f'content="Explore {count} resources',
|
| 125 |
f">{count}</b><span>resources</span>",
|
| 126 |
f"Filter {count} resources",
|
|
|
|
| 127 |
f'"version": "{version}"',
|
| 128 |
],
|
| 129 |
failures,
|
| 130 |
)
|
| 131 |
require(ROOT / "meta" / "social-preview.html", [f">{count}</b>"], failures)
|
| 132 |
-
require(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
require(ROOT / "posts" / "launch.zh-CN.md", [f"# Awesome Loop Engineering v{version}", f"{count} 篇论文"], failures)
|
| 134 |
require(ROOT / "meta" / "DISTRIBUTION.md", [f"v{version}", f"{count} resources"], failures)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
|
| 136 |
for translation in sorted(ROOT.glob("README.*.md")):
|
| 137 |
require(translation, [count], failures)
|
|
@@ -143,6 +170,25 @@ def main() -> int:
|
|
| 143 |
failures.append(f"data/resources.csv: expected {count} rows, found {csv_count}")
|
| 144 |
validate_resource_rows(resource_rows, failures)
|
| 145 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
site_payload = json.loads((ROOT / "docs" / "assets" / "resources.json").read_text(encoding="utf-8"))
|
| 147 |
if site_payload.get("count") != int(count) or len(site_payload.get("resources", [])) != int(count):
|
| 148 |
failures.append("docs/assets/resources.json: count or resources array is stale")
|
|
@@ -157,8 +203,9 @@ def main() -> int:
|
|
| 157 |
return 1
|
| 158 |
|
| 159 |
print(
|
| 160 |
-
f"Validated {count} resources, {context['
|
| 161 |
-
f"{context['
|
|
|
|
| 162 |
)
|
| 163 |
return 0
|
| 164 |
|
|
|
|
| 107 |
context = project_context()
|
| 108 |
count = context["RESOURCE_COUNT"]
|
| 109 |
version = context["VERSION"]
|
| 110 |
+
source_summary = (
|
| 111 |
+
f"{context['REACHABLE_COUNT']} public links opened successfully, "
|
| 112 |
+
f"{context['RESTRICTED_COUNT']} required access, "
|
| 113 |
+
f"{context['LOCAL_COUNT']} pointed to files in this repository"
|
| 114 |
+
)
|
| 115 |
failures: list[str] = []
|
| 116 |
|
| 117 |
require(
|
|
|
|
| 119 |
[
|
| 120 |
f"resources-{count}-",
|
| 121 |
f"**{count} resources**",
|
| 122 |
+
source_summary,
|
| 123 |
+
f"**{context['RUNNABLE_COUNT']} runtime starters**: {context['EXECUTABLE_COUNT']} dependency-light executables plus {context['RUNTIME_TEMPLATE_COUNT']} copy/paste runtime templates",
|
| 124 |
+
f"**{context['LANGUAGE_COUNT']} language entry points**",
|
| 125 |
],
|
| 126 |
failures,
|
| 127 |
)
|
|
|
|
| 131 |
f'content="Explore {count} resources',
|
| 132 |
f">{count}</b><span>resources</span>",
|
| 133 |
f"Filter {count} resources",
|
| 134 |
+
f"{context['REACHABLE_COUNT']} public links opened successfully, {context['RESTRICTED_COUNT']} required access",
|
| 135 |
f'"version": "{version}"',
|
| 136 |
],
|
| 137 |
failures,
|
| 138 |
)
|
| 139 |
require(ROOT / "meta" / "social-preview.html", [f">{count}</b>"], failures)
|
| 140 |
+
require(
|
| 141 |
+
ROOT / "posts" / "launch.md",
|
| 142 |
+
[
|
| 143 |
+
f"# Awesome Loop Engineering v{version}",
|
| 144 |
+
f"{count} resources",
|
| 145 |
+
f"{context['MODEL_COUNT']} model-layer resources",
|
| 146 |
+
f"{context['FIELD_COUNT']}-field CSV",
|
| 147 |
+
f"{context['LANGUAGE_COUNT']} language entry points",
|
| 148 |
+
],
|
| 149 |
+
failures,
|
| 150 |
+
)
|
| 151 |
require(ROOT / "posts" / "launch.zh-CN.md", [f"# Awesome Loop Engineering v{version}", f"{count} 篇论文"], failures)
|
| 152 |
require(ROOT / "meta" / "DISTRIBUTION.md", [f"v{version}", f"{count} resources"], failures)
|
| 153 |
+
require(
|
| 154 |
+
ROOT / "design-qa.md",
|
| 155 |
+
[
|
| 156 |
+
f"returns {context['MODEL_COUNT']} of {count} resources ({context['MODEL_PAPER_COUNT']} papers plus Awesome Loop Models)",
|
| 157 |
+
f"{context['REACHABLE_COUNT']} public sources reachable, {context['RESTRICTED_COUNT']} access-restricted, {context['LOCAL_COUNT']} repository-native",
|
| 158 |
+
],
|
| 159 |
+
failures,
|
| 160 |
+
)
|
| 161 |
+
require(ROOT / "data" / "README.md", [f"Download all {count} resources"], failures)
|
| 162 |
|
| 163 |
for translation in sorted(ROOT.glob("README.*.md")):
|
| 164 |
require(translation, [count], failures)
|
|
|
|
| 170 |
failures.append(f"data/resources.csv: expected {count} rows, found {csv_count}")
|
| 171 |
validate_resource_rows(resource_rows, failures)
|
| 172 |
|
| 173 |
+
with (ROOT / "data" / "resource_source_audit.csv").open(encoding="utf-8", newline="") as handle:
|
| 174 |
+
audit_rows = list(csv.DictReader(handle))
|
| 175 |
+
if len(audit_rows) != int(count):
|
| 176 |
+
failures.append(f"data/resource_source_audit.csv: expected {count} rows, found {len(audit_rows)}")
|
| 177 |
+
audit_statuses: dict[str, int] = {}
|
| 178 |
+
for row in audit_rows:
|
| 179 |
+
status = row.get("audit_status", "")
|
| 180 |
+
audit_statuses[status] = audit_statuses.get(status, 0) + 1
|
| 181 |
+
expected_statuses = {
|
| 182 |
+
"ok": int(context["REACHABLE_COUNT"]),
|
| 183 |
+
"restricted": int(context["RESTRICTED_COUNT"]),
|
| 184 |
+
"local_ok": int(context["LOCAL_COUNT"]),
|
| 185 |
+
}
|
| 186 |
+
if audit_statuses != expected_statuses:
|
| 187 |
+
failures.append(
|
| 188 |
+
"data/resource_source_audit.csv: status counts do not match the generated resource exports "
|
| 189 |
+
f"({audit_statuses!r} != {expected_statuses!r})"
|
| 190 |
+
)
|
| 191 |
+
|
| 192 |
site_payload = json.loads((ROOT / "docs" / "assets" / "resources.json").read_text(encoding="utf-8"))
|
| 193 |
if site_payload.get("count") != int(count) or len(site_payload.get("resources", [])) != int(count):
|
| 194 |
failures.append("docs/assets/resources.json: count or resources array is stale")
|
|
|
|
| 203 |
return 1
|
| 204 |
|
| 205 |
print(
|
| 206 |
+
f"Validated {count} resources, {context['MODEL_COUNT']} model-layer resources, "
|
| 207 |
+
f"{context['PATTERN_COUNT']} patterns, {context['CONTRACT_COUNT']} contracts, "
|
| 208 |
+
f"{context['RUNNABLE_COUNT']} runtime starters, and release v{version}."
|
| 209 |
)
|
| 210 |
return 0
|
| 211 |
|