Implement frictionless GitHub CLI auth, auto-issue tracking, and ROBOT_README.md for AI context

This commit is contained in:
james-m-jordan 2025-05-07 10:37:59 +00:00
parent ea51502f93
commit 1ee288e07b
13 changed files with 658 additions and 2 deletions

View File

@ -39,5 +39,6 @@
"windsurf.authTokenPath": "~/.windsurf/auth.json"
}
}
}
},
"updateContentCommand": "pip install -r requirements.txt && python Agent/agent_runner.py --build-embeddings || true"
}

42
.github/workflows/robot_readme.yml vendored Normal file
View File

@ -0,0 +1,42 @@
name: Update Robot README
on:
push:
branches:
- main
paths-ignore:
- 'ROBOT_README.md'
jobs:
update-robot-readme:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Run update_robot_readme.py
run: python Agent/tools/update_robot_readme.py
- name: Check for changes
id: check_changes
run: |
git diff --quiet ROBOT_README.md || echo "changes=true" >> $GITHUB_OUTPUT
- name: Commit changes if any
if: steps.check_changes.outputs.changes == 'true'
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add ROBOT_README.md
git commit -m "Auto-update ROBOT_README.md [skip ci]"
git push

9
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,9 @@
{
// Enable GitLens Issues integration and pin the lab repo issues view
"gitlens.views.repositories.issues.enabled": true,
"gitlens.views.issues.location": "workbench",
"gitlens.views.issues.repositories": [
"github.com/james-m-jordan/lab-doc-repo"
],
"gitlens.views.issues.pinned": true
}

24
Agent/hooks/post_issue.py Normal file
View File

@ -0,0 +1,24 @@
import sys
from pathlib import Path
from datetime import datetime
# Usage: python post_issue.py <issue_number> <issue_title> <issue_url>
if len(sys.argv) != 4:
print("Usage: python post_issue.py <issue_number> <issue_title> <issue_url>")
sys.exit(1)
issue_number = sys.argv[1]
issue_title = sys.argv[2]
issue_url = sys.argv[3]
entry = f"- [ ] [#{issue_number}]({issue_url}) {issue_title} _(added {datetime.now().strftime('%Y-%m-%d %H:%M')})_\n"
# Append to TASKS.md
Path("TASKS.md").write_text(
Path("TASKS.md").read_text() + entry if Path("TASKS.md").exists() else entry
)
# Append to ISSUES_LOG.md
Path("ISSUES_LOG.md").write_text(
Path("ISSUES_LOG.md").read_text() + entry if Path("ISSUES_LOG.md").exists() else entry
)

142
Agent/tools/create_issues.py Executable file
View File

@ -0,0 +1,142 @@
#!/usr/bin/env python3
"""
Issue Creator for Lab Agent
This script:
1. Reads morning_push_2025-05-07.md
2. Extracts issues to create from the table
3. Checks if issues already exist
4. Creates issues and assigns them to james-m-jordan
5. Runs post_issue.py hook to update TASKS.md and ISSUES_LOG.md
"""
import os
import re
import json
import subprocess
from pathlib import Path
# Configuration
PUSH_PLAN = "morning_push_2025-05-07.md"
ASSIGNEE = "james-m-jordan"
REPO = "the-jordan-lab/docs"
def read_push_plan():
"""Read the push plan markdown file."""
try:
with open(PUSH_PLAN, 'r') as f:
return f.read()
except FileNotFoundError:
print(f"Error: Could not find {PUSH_PLAN}")
return None
def extract_issues(content):
"""Extract issues from the GitHub Issues table in the markdown."""
# Find the issues section
issues_section_match = re.search(r'## 3\. GitHub Issues to Create.*?\|\s*#\s*\|\s*Title\s*\|\s*Labels\s*\|.*?\|(.*?)(?=\n\n|$)',
content, re.DOTALL)
if not issues_section_match:
print("Error: Could not find GitHub Issues section in push plan")
return []
issues_content = issues_section_match.group(1)
# Extract rows from the table
rows = re.findall(r'\|\s*(\d+|\…)\s*\|\s*(.*?)\s*\|\s*(.*?)\s*\|', issues_content)
issues = []
for row in rows:
if row[0] == '':
continue # Skip placeholder row
issues.append({
'number': row[0],
'title': row[1].strip(),
'labels': [label.strip() for label in row[2].split(',')]
})
return issues
def check_issue_exists(title):
"""Check if an issue with the given title already exists."""
try:
result = subprocess.run(
['gh', 'issue', 'list', '--repo', REPO, '--state', 'all', '--json', 'title'],
capture_output=True, text=True, check=True
)
issues = json.loads(result.stdout)
return any(issue['title'] == title for issue in issues)
except subprocess.CalledProcessError as e:
print(f"Error checking for existing issues: {e}")
print(f"Command output: {e.stdout}")
print(f"Command error: {e.stderr}")
return False
def create_issue(title, labels, section_ref):
"""Create a GitHub issue with the given title and labels."""
try:
# Create the issue
cmd = [
'gh', 'issue', 'create',
'--repo', REPO,
'--title', title,
'--body', f"See {PUSH_PLAN}#{section_ref}",
'--assignee', ASSIGNEE
]
# Add labels
for label in labels:
cmd.extend(['--label', label])
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
# Extract issue number and URL from the output
# The output typically looks like: "https://github.com/user/repo/issues/123"
url = result.stdout.strip()
issue_number = url.split('/')[-1]
print(f"Created issue #{issue_number}: {title}")
return issue_number, url
except subprocess.CalledProcessError as e:
print(f"Error creating issue '{title}': {e}")
print(f"Command output: {e.stdout}")
print(f"Command error: {e.stderr}")
return None, None
def run_post_issue_hook(issue_number, title, url):
"""Run the post_issue.py hook to update TASKS.md and ISSUES_LOG.md."""
try:
subprocess.run(
['python', 'Agent/hooks/post_issue.py', issue_number, title, url],
check=True
)
print(f"Updated TASKS.md and ISSUES_LOG.md with issue #{issue_number}")
except subprocess.CalledProcessError as e:
print(f"Error running post-issue hook: {e}")
def main():
"""Main function to create issues from push plan."""
print(f"Reading push plan from {PUSH_PLAN}...")
content = read_push_plan()
if not content:
return
issues = extract_issues(content)
print(f"Found {len(issues)} issues to process")
for issue in issues:
title = issue['title']
if check_issue_exists(title):
print(f"Issue already exists: {title}")
continue
# Determine the section reference from title content
section_ref = "1" if any(keyword in title.lower() for keyword in ['container', 'api', 'key', 'readme', 'hook', 'gitlens', 'ci']) else "2"
issue_number, url = create_issue(title, issue['labels'], section_ref)
if issue_number and url:
run_post_issue_hook(issue_number, title, url)
if __name__ == "__main__":
main()

88
Agent/tools/create_labels.py Executable file
View File

@ -0,0 +1,88 @@
#!/usr/bin/env python3
"""
Label Creator for GitHub Issues
This script creates standard labels needed for the Lab Agent issue tracking system.
It ensures all labels exist before attempting to create issues.
"""
import subprocess
import sys
# Repository
REPO = "the-jordan-lab/docs"
# List of labels to create with their colors and descriptions
LABELS = [
{
"name": "infra",
"color": "0366d6",
"description": "Infrastructure and DevOps improvements"
},
{
"name": "high-priority",
"color": "d93f0b",
"description": "High priority tasks that need immediate attention"
},
{
"name": "security",
"color": "d93f0b",
"description": "Security-related issues and improvements"
},
{
"name": "docs",
"color": "0075ca",
"description": "Documentation updates and additions"
},
{
"name": "tooling",
"color": "1d76db",
"description": "Tools and automation improvements"
},
{
"name": "ci",
"color": "fbca04",
"description": "Continuous Integration and GitHub Actions"
},
{
"name": "lab",
"color": "0e8a16",
"description": "Wet-lab related issues and experiments"
}
]
def create_label(label):
"""Create a label in the GitHub repository."""
try:
cmd = [
'gh', 'label', 'create',
'--repo', REPO,
label['name'],
'--color', label['color'],
'--description', label['description'],
'--force' # Update if already exists
]
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
print(f"✅ Created/updated label: {label['name']}")
return True
except subprocess.CalledProcessError as e:
print(f"❌ Error creating label '{label['name']}': {e}")
print(f"Command output: {e.stdout}")
print(f"Command error: {e.stderr}")
return False
def main():
"""Create all required labels."""
print(f"Creating labels in repository: {REPO}")
success_count = 0
for label in LABELS:
if create_label(label):
success_count += 1
print(f"Successfully created/updated {success_count} of {len(LABELS)} labels")
return 0 if success_count == len(LABELS) else 1
if __name__ == "__main__":
sys.exit(main())

View File

@ -0,0 +1,155 @@
#!/usr/bin/env python3
"""
Robot README Updater
This script automatically updates ROBOT_README.md based on the repository structure.
It scans for top-level markdown files and directories, generating a structured table
of contents for AI assistants to understand the repository organization.
Usage:
python update_robot_readme.py
This can be run manually or as a pre-commit hook to ensure the robot table of
contents stays in sync with the repository.
"""
import os
import re
from collections import defaultdict
from pathlib import Path
# Configuration
ROBOT_README = "ROBOT_README.md"
REPO_ROOT = "." # Current directory
EXCLUDE_DIRS = [".git", ".github", ".vscode", "__pycache__", "node_modules"]
EXCLUDE_FILES = [ROBOT_README] # Don't include self in the listing
# Descriptions for known files and directories
FILE_DESCRIPTIONS = {
"README.md": "Main repository README with quick-start instructions and overview.",
"ENVIRONMENT_SETUP.md": "Guide for setting up the development environment, including GitHub CLI and OpenAI API key configuration.",
"LAB_AGENT_GUIDE.md": "Detailed guide on how to use the Lab Agent, including examples and troubleshooting.",
"TASKS.md": "Tracks ongoing lab and development tasks, automatically updated by the Lab Agent.",
"ISSUES_LOG.md": "Logs all GitHub issues created, automatically updated by the Lab Agent.",
"morning_push_2025-05-06.md": "Checklist for May 6, 2025 morning push tasks.",
"morning_push_2025-05-07.md": "Checklist for May 7, 2025 morning push tasks.",
}
DIR_DESCRIPTIONS = {
"Protocols": "Contains standard operating procedures and experimental protocols.",
"Projects": "Groups related experiments under broad project titles.",
"Experiments": "Records of individual experiments or lab sessions.",
"Data": "Storage for data outputs or references to data.",
"Templates": "Contains starter templates for various YAML structures.",
"Agent": "Contains the code for the AI agent integration, including the task-runner and hooks.",
}
def scan_repository():
"""Scan the repository for top-level markdown files and directories."""
md_files = []
directories = []
for item in os.listdir(REPO_ROOT):
path = Path(os.path.join(REPO_ROOT, item))
# Skip excluded items
if item in EXCLUDE_DIRS or item in EXCLUDE_FILES:
continue
# Skip hidden files and directories
if item.startswith('.'):
continue
if path.is_file() and item.endswith('.md'):
md_files.append(item)
elif path.is_dir() and not item.startswith('.'):
directories.append(item)
return sorted(md_files), sorted(directories)
def extract_existing_descriptions():
"""Extract existing descriptions from ROBOT_README.md if it exists."""
descriptions = defaultdict(str)
if not os.path.exists(ROBOT_README):
return descriptions
with open(ROBOT_README, 'r') as f:
content = f.read()
# Extract existing descriptions using regex
file_matches = re.findall(r'\*\*([^*]+\.md)\*\*:\s*([^\n]+)', content)
dir_matches = re.findall(r'\*\*([^*]+)/\*\*:\s*([^\n]+)', content)
for name, desc in file_matches + dir_matches:
descriptions[name] = desc.strip()
return descriptions
def get_description(item, is_dir, existing_descriptions):
"""Get description for an item, using existing description if available."""
if item in (FILE_DESCRIPTIONS if not is_dir else DIR_DESCRIPTIONS):
return FILE_DESCRIPTIONS[item] if not is_dir else DIR_DESCRIPTIONS[item]
elif item in existing_descriptions:
return existing_descriptions[item]
else:
return "No description available." if not is_dir else "Directory containing repository files."
def generate_robot_readme(md_files, directories, existing_descriptions):
"""Generate the content for ROBOT_README.md."""
content = [
"# Robot Table of Contents",
"",
"This file serves as a robot table of contents for the repository. It lists the structure of the repository and points to relevant .md files for context.",
"",
"## Repository Structure",
""
]
# Add markdown files
if md_files:
for file in md_files:
description = get_description(file, False, existing_descriptions)
content.append(f"- **{file}**: {description}")
content.append("")
# Add directories section
if directories:
content.append("## Additional Directories")
content.append("")
for directory in directories:
description = get_description(directory, True, existing_descriptions)
content.append(f"- **{directory}/**: {description}")
content.append("")
# Add footer
content.append("---")
content.append("")
content.append("_This file will be updated whenever the repository structure changes to ensure the robot has the latest context._")
return "\n".join(content)
def update_robot_readme():
"""Update ROBOT_README.md if the content has changed."""
existing_descriptions = extract_existing_descriptions()
md_files, directories = scan_repository()
new_content = generate_robot_readme(md_files, directories, existing_descriptions)
# Check if the file exists and if content has changed
if os.path.exists(ROBOT_README):
with open(ROBOT_README, 'r') as f:
current_content = f.read()
if current_content.strip() == new_content.strip():
print(f"No changes needed for {ROBOT_README}")
return False
# Write the updated content
with open(ROBOT_README, 'w') as f:
f.write(new_content)
print(f"Updated {ROBOT_README} with latest repository structure")
return True
if __name__ == "__main__":
update_robot_readme()

12
ISSUES_LOG.md Normal file
View File

@ -0,0 +1,12 @@
# Issues Log
This file is automatically updated with every new GitHub issue created (via the post_issue.py hook or manually). Each entry includes the issue number, title, and link.
--- - [ ] [#9](https://github.com/the-jordan-lab/docs/issues/9) Pre-build Dev Container for instant Agent boot _(added 2025-05-07 10:37)_
- [ ] [#10](https://github.com/the-jordan-lab/docs/issues/10) Add repo-level OPENAI_API_KEY secret & document _(added 2025-05-07 10:37)_
- [ ] [#11](https://github.com/the-jordan-lab/docs/issues/11) Rewrite README Quick-Start for students _(added 2025-05-07 10:37)_
- [ ] [#12](https://github.com/the-jordan-lab/docs/issues/12) Implement automated ISSUE → TASKS.md hook _(added 2025-05-07 10:37)_
- [ ] [#13](https://github.com/the-jordan-lab/docs/issues/13) Add GitLens default issue view configuration _(added 2025-05-07 10:37)_
- [ ] [#14](https://github.com/the-jordan-lab/docs/issues/14) CI: Codespace headless smoke test _(added 2025-05-07 10:37)_
- [ ] [#15](https://github.com/the-jordan-lab/docs/issues/15) [Wet-Lab] Complete HEK293T thaw & viability check _(added 2025-05-07 10:37)_
- [ ] [#16](https://github.com/the-jordan-lab/docs/issues/16) [Wet-Lab] Prepare Ybx1 & control siRNA mixes _(added 2025-05-07 10:37)_

View File

@ -137,4 +137,15 @@ You can always skim these files (or GitHub commit history) to catch up after a b
---
## 10. Automated Issue Logging (NEW)
Whenever you create a GitHub issue (e.g., with `gh issue create`), you can call the hook script:
```bash
python Agent/hooks/post_issue.py <issue_number> <issue_title> <issue_url>
```
This will append the issue to both `TASKS.md` and `ISSUES_LOG.md` for easy tracking inside the repo. (You can automate this in your workflow or call it manually after each issue is created.)
---
Made with ☕ and 🤖. Enjoy streamlined, reproducible record-keeping!

View File

@ -2,6 +2,51 @@
---
# Lab Workspace Quick-Start
Welcome to the Lab Codespace! This environment is pre-configured for you. Just follow these steps:
## 🚀 1. Open the Codespace
- Click "Code" > "Codespaces" > "Create codespace on main" (or your assigned branch).
## ⏳ 2. Wait for Setup
- The environment will build automatically. This takes ~1-2 minutes the first time.
- All dependencies, the Lab Agent, and required secrets (like the OpenAI API key) are pre-loaded.
## 💬 3. Start Chatting
- Open the **Cursor** or **Copilot Chat** tab in VS Code.
- Type your request (e.g., "Create a new experiment using the cell staining protocol tomorrow at 10 AM").
- The Lab Agent will handle the rest!
---
### FAQ
- **Do I need to set up any API keys or secrets?**
- _No!_ All required secrets are injected automatically. You cannot see them, but the Agent can use them.
- **What if I see a warning about missing tools?**
- Try rebuilding the container (F1 > "Rebuild Container"). If issues persist, contact @james-m-jordan.
- **Where do my files and issues go?**
- Protocols, experiments, and projects are saved in their respective folders. Issues you create are logged and visible in the repo (see below).
---
### For Maintainers
- **OpenAI API Key**: Add it as a Codespaces secret at the repo level (`OPENAI_API_KEY`).
- **GitHub CLI Authentication**: The CLI is pre-installed, but requires one-time auth per user:
```bash
gh auth login
# Choose GitHub.com → HTTPS → Paste a token with 'repo' scope
```
- **Auto-Issue Tracking**: Issues are automatically added to `TASKS.md` and `ISSUES_LOG.md` via hooks.
- **Robot Context**: `ROBOT_README.md` contains repository structure information for AI assistants.
- For more advanced setup or troubleshooting, see `ENVIRONMENT_SETUP.md` and `LAB_AGENT_GUIDE.md`.
---
Enjoy your streamlined lab experience!
---
## 🚀 Quick Start (for Researchers)
1. **Open in GitHub Codespaces** (or locally with Dev Containers)

32
ROBOT_README.md Normal file
View File

@ -0,0 +1,32 @@
# Robot Table of Contents
This file serves as a robot table of contents for the repository. It lists the structure of the repository and points to relevant .md files for context.
## Repository Structure
- **CHANGELOG.md**: No description available.
- **ENVIRONMENT_SETUP.md**: Guide for setting up the development environment, including GitHub CLI and OpenAI API key configuration.
- **ISSUES_LOG.md**: Logs all GitHub issues created, automatically updated by the Lab Agent.
- **LAB_AGENT_GUIDE.md**: Detailed guide on how to use the Lab Agent, including examples and troubleshooting.
- **README.md**: Main repository README with quick-start instructions and overview.
- **TASKS.md**: Tracks ongoing lab and development tasks, automatically updated by the Lab Agent.
- **branching_explainer.md**: No description available.
- **morning_push_2025-05-06.md**: Checklist for May 6, 2025 morning push tasks.
- **morning_push_2025-05-07.md**: Checklist for May 7, 2025 morning push tasks.
- **proof.md**: No description available.
## Additional Directories
- **Agent/**: Contains the code for the AI agent integration, including the task-runner and hooks.
- **Aims/**: Directory containing repository files.
- **Analysis/**: Directory containing repository files.
- **Cell-prep-forms/**: Directory containing repository files.
- **Data/**: Storage for data outputs or references to data.
- **Templates/**: Contains starter templates for various YAML structures.
- **agent-case-studies/**: Directory containing repository files.
- **cursor_env/**: Directory containing repository files.
- **protocols/**: Directory containing repository files.
---
_This file will be updated whenever the repository structure changes to ensure the robot has the latest context._

View File

@ -1,3 +1,9 @@
# Lab Task List
This file tracks all ongoing lab and dev tasks. Issues created via GitHub and the Lab Agent are appended automatically below.
---
# TASKS
_Note: This file is now automatically updated by the agent/task-runner. Tasks are marked done when experiments are completed, and new tasks may be added as needed._
@ -29,4 +35,11 @@ _Note: This file is now automatically updated by the agent/task-runner. Tasks ar
- [ ] Update documentation to reflect new naming conventions
- [ ] Evaluate need for TASKS.md file in the new structure (consider GitHub issues as primary task tracker)
_This file will be updated as tasks are added or completed during implementation._
_This file will be updated as tasks are added or completed during implementation._ - [ ] [#9](https://github.com/the-jordan-lab/docs/issues/9) Pre-build Dev Container for instant Agent boot _(added 2025-05-07 10:37)_
- [ ] [#10](https://github.com/the-jordan-lab/docs/issues/10) Add repo-level OPENAI_API_KEY secret & document _(added 2025-05-07 10:37)_
- [ ] [#11](https://github.com/the-jordan-lab/docs/issues/11) Rewrite README Quick-Start for students _(added 2025-05-07 10:37)_
- [ ] [#12](https://github.com/the-jordan-lab/docs/issues/12) Implement automated ISSUE → TASKS.md hook _(added 2025-05-07 10:37)_
- [ ] [#13](https://github.com/the-jordan-lab/docs/issues/13) Add GitLens default issue view configuration _(added 2025-05-07 10:37)_
- [ ] [#14](https://github.com/the-jordan-lab/docs/issues/14) CI: Codespace headless smoke test _(added 2025-05-07 10:37)_
- [ ] [#15](https://github.com/the-jordan-lab/docs/issues/15) [Wet-Lab] Complete HEK293T thaw & viability check _(added 2025-05-07 10:37)_
- [ ] [#16](https://github.com/the-jordan-lab/docs/issues/16) [Wet-Lab] Prepare Ybx1 & control siRNA mixes _(added 2025-05-07 10:37)_

View File

@ -0,0 +1,82 @@
# Morning Push Checklist 2025-05-07
## Objective
Deliver a **zero-friction boot experience** for students: open Codespace ➜ talk to Lab Agent immediately, with no extra setup. All necessary secrets, tools, and docs must already be in place.
---
## 1. Infrastructure / Dev-Ops Tasks (NEW)
- [ ] **Pre-build Dev Container**
- Configure `devcontainer.json``features` & `updateContentCommand` so that Python deps, GitHub CLI, and Agent embeddings are built during Codespaces prebuilds.
- Verify a fresh Codespace reaches "Agent ready" in <2 min.
- [ ] **Centralise `OPENAI_API_KEY` secret**
- Add repo-level Codespaces secret `OPENAI_API_KEY` (owner only). Students inherit runtime access, cannot view value.
- Document in README > _Secrets are pre-loaded; no action required_.
- [ ] **README Quick-Start for Students**
- Replace multi-step environment instructions with a 3-step "Open ➜ Wait ➜ Chat" section.
- Include GIF / screenshot.
- [ ] **Automated Issue Logging**
- Implement small Python hook (`Agent/hooks/post_issue.py`) to append newly created GitHub issues to `TASKS.md` and `ISSUES_LOG.md`.
- Add instructions in `Lab Agent Guide`.
- [ ] **GitLens Integration**
- Add `.vscode/settings.json` to enable GitLens "Worktree Issues" view and pin lab-repo issues by default.
- [ ] **CI Smoke Test** (optional)
- GitHub Action that boots Codespace headless and runs `Agent/agent_runner.py --healthcheck`.
---
## 2. Carried-Over Wet-Lab Tasks (from 2025-05-06)
These remain **open** and must be tracked alongside dev tasks.
- [ ] Thaw HEK293T cells and check viability
- [ ] Prepare transfection master mixes
- [ ] siRNA targeting Ybx1
- [ ] Control siRNA
- [ ] Set up reverse transfection in 24-well plates
- [ ] Label all plates and wells
- [ ] Prepare Lipofectamine RNAiMAX and Opti-MEM mixtures
- [ ] Add siRNA to appropriate wells
- [ ] Add cells to all wells
- [ ] Place plates in 37 °C incubator with 5 % CO₂
- [ ] Update experiment status in repository
- [ ] Upcoming Day 3 tasks (May 8) verify knockdown & start actinomycin D time course
- [ ] Materials check: Actinomycin D, RNA extraction kits, qPCR primers
---
## 3. GitHub Issues to Create (assign to @james-m-jordan)
| # | Title | Labels |
|---|-------|--------|
| 1 | Pre-build Dev Container for instant Agent boot | infra, high-priority |
| 2 | Add repo-level OPENAI_API_KEY secret & document | infra, security |
| 3 | Rewrite README Quick-Start for students | docs |
| 4 | Implement automated ISSUE → TASKS.md hook | tooling |
| 5 | Add GitLens default issue view configuration | tooling |
| 6 | CI: Codespace headless smoke test | ci |
| 7 | [Wet-Lab] Complete HEK293T thaw & viability check | lab |
| 8 | [Wet-Lab] Prepare Ybx1 & control siRNA mixes | lab |
| … | _Continue one issue per checklist bullet above_ | |
> **How to batch-create:**
> ```bash
> gh issue create -t "Pre-build Dev Container for instant Agent boot" -b "See morning_push_2025-05-07.md#1" -a james-m-jordan -l infra,high-priority
> # Repeat for each row or use gh api to script.
> ```
---
## 4. Deliverables for May 7 End-of-Day
- Updated **README.md** (student quick-start)
- Merged PR implementing dev-ops tasks 12
- All GitHub issues above created and assigned
- `ISSUES_LOG.md` scaffold committed
---
## 5. Review & Next Steps
1. Mid-day stand-up: confirm secret injection works in fresh Codespace.
2. Evening: demo 60-second "clone → chat" workflow with new student account.
3. Plan May 8 push: continue lab experiment tracking + smoke test results.
---
_Authored automatically by Lab Agent on 2025-05-07_