Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,9 @@ repos:
language: system
files: ^\.github/workflows/lint\.yml$
pass_filenames: false
- id: lint-agent-docs
name: lint agent doc references and structure
entry: ./hack/lint-agent-docs
language: script
files: ^(harness/|docs/)
pass_filenames: false
Comment on lines +49 to +54

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Protected paths modified in pr 📜 Skill insight § Compliance

This PR modifies protected governance/infrastructure paths (.pre-commit-config.yaml and hack/).
Per the compliance checklist, changes under protected paths must be explicitly flagged for required
human review and must not be auto-approved.
Agent Prompt
## Issue description
This PR changes protected governance/infrastructure files, which require explicit authorization/justification and mandatory human review signals.

## Issue Context
Protected paths include `.pre-commit-config.yaml` and `hack/`. The PR description contains a summary, but it does not include an explicit linked issue/ADR reference that authorizes the governance/tooling change.

## Fix Focus Areas
- .pre-commit-config.yaml[49-54]
- hack/lint-agent-docs[1-6]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

10 changes: 9 additions & 1 deletion docs/scribe.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ Reads Google Drive meeting notes, maps discussion topics to the GitHub issue bac

The scribe agent runs on a schedule or via manual trigger.

## Commands

The scribe agent does not accept slash commands.

## Control labels

The scribe agent does not use control labels.

## Configuration

Register the agent in your `.fullsend` config (ADR 0058):
Expand All @@ -24,7 +32,7 @@ fullsend agent add \
--fullsend-dir .
```

### Environment variables
### Variables

Per ADR 0049, scribe configuration uses the `SCRIBE_` prefix.

Expand Down
139 changes: 139 additions & 0 deletions hack/lint-agent-docs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#!/bin/bash
# Lint: every harness YAML must have a doc: field pointing to an existing file.
# Also checks that agent docs follow a consistent structure.
set -euo pipefail
shopt -s nullglob

REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
HARNESS_DIR="$REPO_ROOT/harness"

errors=0

echo "Checking harness files for doc: field..."
echo "================================================"

for yaml_file in "$HARNESS_DIR"/*.yaml; do
name="$(basename "$yaml_file")"
doc_value="$(grep -E '^doc:' "$yaml_file" | sed 's/^doc:[[:space:]]*//' || true)"

if [[ -z "$doc_value" ]]; then
echo " ERROR: $name: missing 'doc:' field"
Comment on lines +1 to +20

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. No linked issue authorization 📜 Skill insight § Compliance

This is a non-trivial change (new linter script and pre-commit integration) but the PR description
does not link to an authorizing issue. The compliance checklist requires an explicit linked issue
for non-trivial work.
Agent Prompt
## Issue description
The PR introduces a new CI/pre-commit linter script (non-trivial change) but lacks a linked issue that authorizes the work.

## Issue Context
The compliance rule requires that non-trivial changes (20+ lines / structural changes) include an explicit linked issue in the PR description.

## Fix Focus Areas
- hack/lint-agent-docs[1-139]
- .pre-commit-config.yaml[49-54]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

errors=$((errors + 1))
continue
fi

doc_path="$REPO_ROOT/$doc_value"
if [[ ! -f "$doc_path" ]]; then
echo " ERROR: $name: doc '$doc_value' does not exist"
errors=$((errors + 1))
continue
fi

echo " $name: OK ($doc_value)"
done

echo ""
echo "Checking agent doc structure..."
echo "================================================"

REQUIRED_SECTIONS="How it helps|Triggers|Commands|Control labels|Configuration|How the agent works|Source"
IFS='|' read -ra SECTION_LIST <<< "$REQUIRED_SECTIONS"

for yaml_file in "$HARNESS_DIR"/*.yaml; do
doc_value="$(grep -E '^doc:' "$yaml_file" | sed 's/^doc:[[:space:]]*//' || true)"
if [[ -z "$doc_value" ]]; then
continue
fi
doc_path="$REPO_ROOT/$doc_value"
if [[ ! -f "$doc_path" ]]; then
continue
fi
doc_basename="$(basename "$doc_value")"

# Check that the top-level heading ends with " Agent"
h1="$(awk 'BEGIN{f=0} /^```/{f=1-f; next} f==0 && /^# [^#]/{sub(/^# /,""); print; exit}' "$doc_path")"
if [[ -n "$h1" ]] && [[ "$h1" != *" Agent" ]]; then
echo " $doc_basename: top heading \"# $h1\" must end with \" Agent\" (e.g. \"# ${h1} Agent\")"
errors=$((errors + 1))
fi
Comment on lines +53 to +58

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

3. Missing h1 not enforced 🐞 Bug ≡ Correctness

hack/lint-agent-docs only validates the H1 suffix when an H1 was found, so a doc with no top-level
"# ..." heading silently passes this check. This weakens the linter’s ability to enforce consistent
agent doc structure in CI.
Agent Prompt
### Issue description
The H1 validation currently only runs when `h1` is non-empty (`[[ -n "$h1" ]]`), which means documents that omit a top-level `# ...` heading will not fail lint.

### Issue Context
This script is now run via pre-commit/CI, so missing H1s should be treated as lint errors to match the intended documentation structure requirements.

### Fix
Treat an empty `h1` as an error (increment `errors`) and print a clear message (e.g., `missing top-level "# ... Agent" heading`). Then keep the existing suffix check for non-empty H1s.

### Fix Focus Areas
- hack/lint-agent-docs[53-58]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


# Extract ## headers outside fenced code blocks
actual_sections="$(awk 'BEGIN{f=0} /^```/{f=1-f; next} f==0 && /^## /{sub(/^## /,""); print}' "$doc_path")"

missing=()
extra=()
for section in "${SECTION_LIST[@]}"; do
if ! echo "$actual_sections" | grep -Fqx "$section"; then
missing+=("$section")
fi
done

while IFS= read -r section; do
[[ -z "$section" ]] && continue
found=false
for required in "${SECTION_LIST[@]}"; do
if [[ "$section" == "$required" ]]; then
found=true
break
fi
done
if [[ "$found" == "false" ]]; then
extra+=("$section")
fi
done <<< "$actual_sections"

if [[ ${#missing[@]} -gt 0 || ${#extra[@]} -gt 0 ]]; then
if [[ ${#missing[@]} -gt 0 ]]; then
echo " $doc_basename: FAIL"
else
echo " $doc_basename: OK (with extra sections)"
fi
for s in "${missing[@]+"${missing[@]}"}"; do
echo " missing: \"## $s\""
errors=$((errors + 1))
done
for s in "${extra[@]+"${extra[@]}"}"; do
echo " info: extra section \"## $s\" — consider adding to REQUIRED_SECTIONS in hack/lint-agent-docs if all agent docs should have it"
done
else
echo " $doc_basename: OK"
fi
done

echo ""
echo "Checking for ### Variables subsection..."
echo "================================================"

for yaml_file in "$HARNESS_DIR"/*.yaml; do
doc_value="$(grep -E '^doc:' "$yaml_file" | sed 's/^doc:[[:space:]]*//' || true)"
if [[ -z "$doc_value" ]]; then
continue
fi
doc_path="$REPO_ROOT/$doc_value"
if [[ ! -f "$doc_path" ]]; then
continue
fi
doc_basename="$(basename "$doc_value")"

# Only check docs that have the Configuration section
if ! awk 'BEGIN{f=0} /^```/{f=1-f; next} f==0 && /^## Configuration/{found=1} END{exit !found}' "$doc_path"; then
continue
fi

# Look for ### Variables under ## Configuration (not just anywhere)
if ! awk 'BEGIN{f=0;c=0} /^```/{f=1-f;next} f{next} /^## Configuration/{c=1;next} /^## /{c=0} c && /^### Variables/{found=1} END{exit !found}' "$doc_path"; then
echo " $doc_basename: missing \"### Variables\" subsection under \"## Configuration\""
errors=$((errors + 1))
else
echo " $doc_basename: OK"
fi
done

echo ""
echo "================================================"
if [[ $errors -gt 0 ]]; then
echo "FAILED: $errors error(s) found"
exit 1
else
echo "OK: All harness files have valid doc references and structure"
fi
Loading