Add broad research scan script + first scan results

- New script: .agents/scripts/research/broad_scan.py — fetches Reddit RSS
  (r/weightroom, r/advancedfitness, r/StrongerByScience) and PubMed
  (resistance training, strength programming, exercise physiology)
  without targeted search bias. Auto-saves to logs/research/.
- First scan: logs/research/2026-06-26-broad-scan.md
  Key finds: low-load RT (40-50% 1RM) validated for reintroduction phase,
  sprinting knee power >> hamstring exercises, new 2026 rehab studies
This commit is contained in:
Jacob Hinkle 2026-06-25 20:59:24 -04:00
parent e3e441c034
commit e226c20161
2 changed files with 292 additions and 0 deletions

View File

@ -0,0 +1,213 @@
#!/usr/bin/env python3
"""
Broad research scan: fetches recent high-signal content from fitness/science
sources without targeted search bias. Run occasionally to catch trends,
new studies, and community discussions.
Sources:
- Reddit: r/weightroom, r/advancedfitness, r/StrongerByScience
- PubMed: recent articles on general resistance training
"""
import json
import urllib.request
import urllib.parse
import time
import sys
from datetime import datetime, timezone
from xml.etree import ElementTree
REDDIT_USER_AGENT = "fitness-agent/1.0 (research script; for personal training logs)"
SOURCES = {
"reddit": [
"weightroom",
"advancedfitness",
"StrongerByScience",
],
"pubmed_terms": [
"resistance training",
"strength training programming",
"exercise physiology",
],
}
def fetch_url(url, max_retries=2):
"""Fetch content from a URL with retries."""
for attempt in range(max_retries):
try:
req = urllib.request.Request(url, headers={"User-Agent": REDDIT_USER_AGENT})
with urllib.request.urlopen(req, timeout=15) as resp:
return resp.read().decode()
except Exception as e:
if attempt < max_retries - 1:
time.sleep(3)
else:
return None
def fetch_reddit_posts(subreddit, limit=10):
"""Fetch top posts from a subreddit via RSS."""
# Use RSS feed (works without auth)
url = f"https://www.reddit.com/r/{subreddit}/hot/.rss?limit={limit}"
content = fetch_url(url)
if not content:
# Fallback: try old.reddit.com
url = f"https://old.reddit.com/r/{subreddit}/hot/.rss?limit={limit}"
content = fetch_url(url)
if not content:
return [{"title": f"[Could not reach r/{subreddit}]", "url": "", "score": 0, "num_comments": 0}]
posts = []
try:
root = ElementTree.fromstring(content)
# RSS namespace
ns = {"": "http://www.w3.org/2005/Atom"}
for entry in root.findall(".//entry", ns):
title_el = entry.find("title", ns)
link_el = entry.find("link", ns)
updated_el = entry.find("updated", ns)
title = title_el.text if title_el is not None else "No title"
link = link_el.get("href", "") if link_el is not None else ""
updated = updated_el.text[:10] if updated_el is not None and updated_el.text else "?"
posts.append({
"title": title,
"url": link,
"score": "?",
"num_comments": "?",
"date": updated,
})
except Exception as e:
return [{"title": f"[Parse error: {e}]", "url": "", "score": 0, "num_comments": 0}]
return posts if posts else [{"title": "No posts found", "url": "", "score": 0, "num_comments": 0}]
def fetch_pubmed_articles(term, max_results=5):
"""Fetch recent PubMed articles on a broad topic."""
base_url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/"
# Search with retmode=json
search_url = (
f"{base_url}esearch.fcgi?"
f"db=pubmed&term={urllib.parse.quote(term)}&"
f"retmax={max_results}&sort=date&retmode=json"
)
content = fetch_url(search_url)
if not content:
return [{"title": f"[Could not reach PubMed for '{term}']", "url": "", "authors": "", "source": ""}]
try:
search_data = json.loads(content)
except json.JSONDecodeError:
return [{"title": f"[Parse error for '{term}']", "url": "", "authors": "", "source": ""}]
id_list = search_data.get("esearchresult", {}).get("idlist", [])
if not id_list:
return [{"title": "No recent articles found", "url": "", "authors": "", "source": ""}]
# Respect NCBI rate limits: max 3 requests per second without API key
time.sleep(1)
# Fetch details as XML
details_url = (
f"{base_url}efetch.fcgi?"
f"db=pubmed&id={','.join(id_list)}&retmode=xml"
)
xml_data = fetch_url(details_url)
if not xml_data:
return [{"title": f"[Could not fetch details for '{term}']", "url": "", "authors": "", "source": ""}]
articles = []
root = ElementTree.fromstring(xml_data)
for article in root.findall(".//PubmedArticle")[:max_results]:
medline = article.find(".//MedlineCitation")
article_data = medline.find(".//Article") if medline is not None else None
if article_data is None:
continue
title_el = article_data.find("ArticleTitle")
title = "".join(title_el.itertext()) if title_el is not None else "No title"
# Authors
author_list = article_data.findall(".//Author")
authors = []
for author in author_list[:3]:
last = author.find("LastName")
fore = author.find("ForeName")
if last is not None:
name = last.text or ""
if fore is not None:
name += f" {fore.text or ''}"
authors.append(name)
author_str = ", ".join(authors) if authors else "Unknown"
# Journal
journal = article_data.find(".//Journal/Title")
journal_str = journal.text if journal is not None else "Unknown journal"
# PMID & link
pmid = medline.find(".//PMID")
pmid_str = pmid.text if pmid is not None else ""
link = f"https://pubmed.ncbi.nlm.nih.gov/{pmid_str}/" if pmid_str else ""
articles.append({
"title": title,
"url": link,
"authors": author_str,
"source": journal_str,
})
return articles if articles else [{"title": "No structured data", "url": "", "authors": "", "source": ""}]
def main():
output = []
output.append(f"# Broad Research Scan — {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}")
output.append(f"_Auto-generated. Not targeted — general scan of recent content._\n")
# --- Reddit ---
output.append("## Reddit\n")
for subreddit in SOURCES["reddit"]:
output.append(f"### r/{subreddit}\n")
posts = fetch_reddit_posts(subreddit)
for post in posts:
date_str = post.get("date", "?")
score_str = post.get("score", "?")
comments_str = post.get("num_comments", "?")
output.append(f"- **{post['title']}**")
if score_str != "?" or comments_str != "?" or date_str != "?":
output.append(f" - Score: {score_str} | Comments: {comments_str} | {date_str}")
output.append(f" - {post['url']}")
output.append("")
# --- PubMed ---
output.append("## PubMed — Recent Articles\n")
for term in SOURCES["pubmed_terms"]:
output.append(f"### Topic: \"{term}\"\n")
articles = fetch_pubmed_articles(term)
for article in articles:
output.append(f"- **{article['title']}**")
if article.get("authors") and article.get("source"):
output.append(f" - {article['authors']} | {article['source']}")
if article.get("url"):
output.append(f" - {article['url']}")
output.append("")
result = "\n".join(output)
print(result)
# Save to dated file
import os
logs_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "logs", "research")
os.makedirs(logs_dir, exist_ok=True)
date_str = datetime.now(timezone.utc).strftime("%Y-%m-%d")
filename = os.path.join(logs_dir, f"{date_str}-broad-scan.md")
with open(filename, "w") as f:
f.write(result)
print(f"\n--- Saved to {filename} ---", file=sys.stderr)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,79 @@
# Broad Research Scan — 2026-06-26 00:58 UTC
_Auto-generated. Not targeted — general scan of recent content._
## Reddit
### r/weightroom
- **[Could not reach r/weightroom]**
- Score: 0 | Comments: 0 | ?
-
### r/advancedfitness
- **[Could not reach r/advancedfitness]**
- Score: 0 | Comments: 0 | ?
-
### r/StrongerByScience
- **[Could not reach r/StrongerByScience]**
- Score: 0 | Comments: 0 | ?
-
## PubMed — Recent Articles
### Topic: "resistance training"
- **Advances in Clinical Management Strategies for Sarcopenia: From Exercise and Nutrition to Pharmacotherapy and Comprehensive Interventions.**
- Xue Fei, Xu Hongyi, Yao Xinlei | Molecular neurobiology
- https://pubmed.ncbi.nlm.nih.gov/42348067/
- **Improved Neuromuscular Performance in Low-Load vs. Moderate-Load Resistance Training Among Young Elite Swimmers.**
- Rodríguez-Rosell David, Neiva Henrique Pereira, Marinho Daniel Almeida | Sports (Basel, Switzerland)
- https://pubmed.ncbi.nlm.nih.gov/42347471/
- **Expression of Concern: Barbalho et al. Effects of Adding Single Joint Exercises to a Resistance Training Programme in Trained Women. Sports 2018, 6, 160.**
- Sports Editorial Office | Sports (Basel, Switzerland)
- https://pubmed.ncbi.nlm.nih.gov/42347464/
- **Effects of Velocity-Based French Contrast Training on Lower-Limb Power and Delivery Kinetics in Medium-Fast Cricket Bowlers: A Randomized Controlled Trial.**
- Zhao Qidong, Li Chunlei | Sports (Basel, Switzerland)
- https://pubmed.ncbi.nlm.nih.gov/42347450/
- **Maximum Sprints Elicit Higher Peak Knee Joint Power than Resistance Training Exercises.**
- Alt Tobias, Clark Kenneth P, Augustsson Jesper | Sports (Basel, Switzerland)
- https://pubmed.ncbi.nlm.nih.gov/42347445/
### Topic: "strength training programming"
- **Advances in Clinical Management Strategies for Sarcopenia: From Exercise and Nutrition to Pharmacotherapy and Comprehensive Interventions.**
- Xue Fei, Xu Hongyi, Yao Xinlei | Molecular neurobiology
- https://pubmed.ncbi.nlm.nih.gov/42348067/
- **Resilience Building and Enhancing Mental Health: A Scoping Review of School-to-University Programs.**
- Nakorn Siriphorn Na, Chandler Genevieve E | Journal of psychosocial nursing and mental health services
- https://pubmed.ncbi.nlm.nih.gov/42347579/
- **Improved Neuromuscular Performance in Low-Load vs. Moderate-Load Resistance Training Among Young Elite Swimmers.**
- Rodríguez-Rosell David, Neiva Henrique Pereira, Marinho Daniel Almeida | Sports (Basel, Switzerland)
- https://pubmed.ncbi.nlm.nih.gov/42347471/
- **Expression of Concern: Barbalho et al. Effects of Adding Single Joint Exercises to a Resistance Training Programme in Trained Women. Sports 2018, 6, 160.**
- Sports Editorial Office | Sports (Basel, Switzerland)
- https://pubmed.ncbi.nlm.nih.gov/42347464/
- **Sex-Based Differences in the Physical Capacity Profile of Regional Fencers.**
- Gaviria Chavarro Javier, Jiménez Trujillo Óscar Hernán, Gómez García Miguel Ángel | Sports (Basel, Switzerland)
- https://pubmed.ncbi.nlm.nih.gov/42347462/
### Topic: "exercise physiology"
- **Advances in Clinical Management Strategies for Sarcopenia: From Exercise and Nutrition to Pharmacotherapy and Comprehensive Interventions.**
- Xue Fei, Xu Hongyi, Yao Xinlei | Molecular neurobiology
- https://pubmed.ncbi.nlm.nih.gov/42348067/
- **Post-diagnosis physical activity in relation to mortality among prostate cancer survivors: a systematic review and meta-analysis.**
- Benker Pauline, Hamann Alina, Leitzmann Michael F | Cancer causes & control : CCC
- https://pubmed.ncbi.nlm.nih.gov/42348026/
- **Effects of High-Impact Exercise on Bone Marker Concentrations During Controlled Low Energy Availability in Recreational Female Runners.**
- Sterringer Trisha, Sale Craig, Morozov Anna | Calcified tissue international
- https://pubmed.ncbi.nlm.nih.gov/42348018/
- **Perspective: Personalized Management of Oxidative and Nitrosative Stress in Post-Exercise Recovery with a Particular Emphasis on the Potential of Micro-Immunotherapy.**
- Jacques Camille, Floris Ilaria | Sports (Basel, Switzerland)
- https://pubmed.ncbi.nlm.nih.gov/42347463/
- **Effects of High-Intensity Interval Training with Blood Flow Restriction Versus Normobaric Hypoxia on Physiological Parameters in Apparently Healthy Young Men.**
- Narrea Vargas Jose Jairo, Castillo-Paredes Antonio, Iman Torres Alexander Javier | Sports (Basel, Switzerland)
- https://pubmed.ncbi.nlm.nih.gov/42347455/