From 86f7368be64240deba35e0a881a4de97fa5f74cd Mon Sep 17 00:00:00 2001 From: Pavel Fadeev Date: Tue, 11 Aug 2026 22:51:38 +0200 Subject: [PATCH] feat: make Epi Log ambient and traceable --- .github/workflows/docs.yml | 24 ++++++ README.md | 96 +++++++++------------- SKILL.md | 158 +++++++------------------------------ references/audit-mode.md | 143 +++++++++++++++++++++++++++++++++ scripts/check-docs.py | 75 ++++++++++++++++++ 5 files changed, 309 insertions(+), 187 deletions(-) create mode 100644 .github/workflows/docs.yml create mode 100644 references/audit-mode.md create mode 100755 scripts/check-docs.py diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..e14ecdb --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,24 @@ +name: Docs + +on: + pull_request: + push: + branches: [main] + +permissions: + contents: read + +jobs: + docs: + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + - name: Validate skill and README + run: python scripts/check-docs.py + - name: Check whitespace + run: git diff --check diff --git a/README.md b/README.md index 42f5ad8..ef3a346 100644 --- a/README.md +++ b/README.md @@ -14,15 +14,26 @@ -**Evidence-first visibility for engineering work.** +**Evidence-first engineering execution and traceability.** -Epi Log is one portable Markdown skill for a daily and trailing-seven-day review of PRs, reviews, tickets, design decisions, meetings, and explicit follow-ups. It helps make outcomes, quality, collaboration, risk reduction, decisions, and follow-through easy to see. It works with whatever read access a harness already has; it does not require a runtime, database, vendor API, or scoring service. +Epi Log is a tiny [Agent Skills](https://agentskills.io)-format core that helps an agent leave useful visibility behind while doing ordinary engineering work. It makes intent, decisions, changes, evidence, outcomes, assumptions, blockers, and follow-up easier to find in the work’s existing artifacts. -Some activity metrics are useful signals but can misrepresent some work when viewed alone. Epi Log adds context and evidence rather than reducing engineering to a scorecard: it reports what can be proved, marks missing evidence as `unknown`, and suggests at most three concrete next actions. +It is designed to be ambient after installation: no separate daily command, diary, database, connector, or reporting ritual is required. Some activity metrics are useful signals but can misrepresent some work when viewed alone; Epi Log adds context and evidence rather than reducing engineering to a scorecard. + +## What it does + +- Drives toward the real outcome and the highest-leverage next step. +- Keeps `intent → decision → change → evidence → outcome` traceable in tickets, PRs, docs, reviews, tests, and handoffs. +- Makes meaningful research, debugging, review, design, coordination, decisions, and blocked work visible when they produce a conclusion, risk reduction, unblock, or reusable artifact. +- Checks one level above for material work: validation, maintainability, reliability, security, rollout, rollback, monitoring, and reuse. +- Repairs genuine visibility gaps at the point of work when authorized, or supplies the smallest precise draft when it cannot act. +- Verifies before handoff and states facts, assumptions, uncertainty, blockers, and follow-up. + +It does not create ceremony for trivial changes, duplicate a diary, invent evidence, or optimize for PR count, lines, hours, streaks, rankings, or other shallow proxies. ## Compatibility -The skill uses the portable [Agent Skills](https://agentskills.io) format. It works with any harness that discovers `SKILL.md`; these are common locations: +The core is plain Markdown with lightweight YAML front matter. It works with any harness that discovers `SKILL.md`; these are common locations: | Harness | Skill location | |---|---| @@ -32,69 +43,38 @@ The skill uses the portable [Agent Skills](https://agentskills.io) format. It wo | **OpenCode** | `~/.config/opencode/skills/epi-log/SKILL.md` or the project skill directory | | **Other harnesses** | Their configured `skills/epi-log/SKILL.md`, or attach the file as instructions | -## Install anywhere - -1. Copy [`SKILL.md`](./SKILL.md) into the harness's skill directory as `epi-log/SKILL.md`. -2. Enable or invoke the skill using the harness's normal mechanism. -3. If the harness has no skill system, tell the agent: `Read /path/to/epi-log/SKILL.md and follow it.` - -Examples of common project/user locations (use the equivalent supported by your harness): - -- Pi: `~/.pi/agent/skills/epi-log/SKILL.md` -- Claude Code: `~/.claude/skills/epi-log/SKILL.md` or `.claude/skills/epi-log/SKILL.md` -- Codex: `~/.codex/skills/epi-log/SKILL.md` or `.codex/skills/epi-log/SKILL.md` -- OpenCode/other harnesses: their configured `skills/epi-log/SKILL.md`, or attach the file as instructions. - -The skill is intentionally plain Markdown with optional YAML front matter. No harness-specific command, SDK, or script is required. - -## Use it - -Ask the agent: - -```text -Run Epi Log for today. -``` - -or: +Skill activation is harness-dependent. For the strongest always-on behavior, load `SKILL.md` from the harness’s baseline/project instructions when that mechanism exists; a skill directory alone may mean “available when relevant,” not literally active on every turn. -```text -Run Epi Log for the trailing 7 days. Use the configured team expectations and save the report. -``` +## Install -If persistence is useful, configure a writable log directory. The default convention is: +Copy [`SKILL.md`](./SKILL.md) into the target harness’s skill directory as `epi-log/SKILL.md`, then enable it using that harness’s normal mechanism. If the harness has no skill system, tell the agent: ```text -.epi-log/ - daily/YYYY-MM-DD.md - weekly/YYYY-Www.md +Read /path/to/epi-log/SKILL.md and follow it as an ambient engineering quality and traceability layer. ``` -An optional `.epi-log/config.md` can state only facts the user/team chooses to provide: +There is no runtime, SDK, vendor API, database, or mandatory connector list. -```yaml -timezone: America/Los_Angeles -sources: [github, jira, slack, gmail, gdrive, meetings] -ticket_system: Jira -adr_convention: docs/adr/ with the organization's template -review_expectation: "team-owned; do not invent a quota" -``` - -## What it makes visible +## Optional audit mode -- PRs are coherent and reviewable, without a fake line-count optimum. -- Merges have observable non-bot human approval before merge and after the relevant revision. -- PRs connect changes to a real outcome and validation, or clearly show the missing evidence. -- The user's weekly reviews and discussions are substantive, without optimizing for comment volume. -- Code, meetings, and commitments map back to epics/tasks in the user's ticket system. -- Material design and architecture decisions have the organization's accepted record. -- Blockers, stale work, contradictions, and forgotten follow-ups have an owner and next action when known. +The core is the normal operating loop. For an explicit retrospective or visibility report, read [`references/audit-mode.md`](references/audit-mode.md) and ask for a daily or trailing-seven-day audit. This mode retains the detailed PR, review, ticket, decision, evidence-gap, and report guidance without making it part of every task. ## Constructive guardrails -- Read-only by default; ask before merging, approving, commenting, messaging, editing tickets/docs, or creating reminders. -- Use bounded, authorized source searches and least privilege. -- Redact secrets, customer data, and unnecessary personal details. -- Missing access is `unknown`, never evidence of inactivity or poor performance. -- Keep visibility focused on outcomes, context, and collaboration—not hours, streaks, commit/line counts, rankings, leaderboards, or behavioral judgments about coworkers. +- Use only authorized sources and existing team conventions. +- Read and write within the user’s permissions; do not merge, approve, comment, message, publish, or edit external artifacts without authorization. +- Separate observed facts, inferences, and `unknown`; missing access is never evidence of “no work.” +- Never claim completion, value, or human review without support. +- Never pad diffs, fragment work artificially, spam comments, fake or rubber-stamp reviews, or manufacture activity. +- Keep visibility focused on outcomes, context, and collaboration—not rankings or behavioral judgments about coworkers. + +## Files -See [`SKILL.md`](./SKILL.md) for the complete, harness-neutral operating instructions and output format. +```text +epi-log/ +├── SKILL.md # tiny ambient core +├── references/audit-mode.md # optional explicit retrospective/report mode +├── assets/ # README banner +├── README.md +└── LICENSE +``` diff --git a/SKILL.md b/SKILL.md index 36abe23..db57cbb 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,152 +1,52 @@ --- name: epi-log -description: Evidence-first daily and weekly visibility for engineering work, reviews, tickets, decisions, and follow-through. +description: Quiet, evidence-first engineering execution and traceability. --- # Epi Log > **Your work is pure rock'n'roll. Let's make sure it is visible now.** -Turn the engineering activity the user has explicitly made available into a short, factual daily or trailing-seven-day log. Make outcomes, quality, collaboration, risk reduction, decisions, and follow-through easy to see, then suggest the smallest actions that improve alignment. +Apply this as a quiet quality-and-visibility layer to relevant engineering work. Do not announce a separate Epi Log process or ask the user to run a visibility pass. -Epi Log is a **constructive visibility and follow-through aid**. Some activity metrics are useful signals but can misrepresent some work when viewed alone; Epi Log adds context and evidence rather than reducing engineering to a scorecard. It complements human judgment and existing team processes: it can verify observable evidence, show gaps, and ask for a decision, but it cannot make people ship, review, document, or approve work. +## Work toward the real outcome -## Non-negotiables +- Understand the intended outcome, then do the requested work first. +- Choose the highest-leverage next step with the inputs and permissions available. +- Keep trivial work trivial. Add process only when the change is material, risky, uncertain, shared, or being handed off. -- **Evidence first.** State observable facts and include a URL, ticket ID, message, document, meeting, or other source reference whenever one exists. -- **Unknown is honest.** Missing access or incomplete data is `unknown`; never turn missing evidence into “no work,” “bad work,” or a guess about intent. -- **Read-only by default.** Never merge or approve a PR, post a comment, send a message, edit a ticket or document, or create a reminder without explicit approval for that exact action. -- **Use metrics as context.** Hours, streaks, commit counts, lines changed, and similar signals are never a verdict about value or performance. Counts are navigation, not scores. -- **Human judgment stays human.** “Enough,” “optimal,” “meaningful,” “valuable,” and the organization’s accepted design format must come from the team or user, not from a made-up universal threshold. -- **Least privilege.** Read only the requested, relevant time window and sources. Treat Slack, email, drive, and meeting data as sensitive. Redact secrets, tokens, customer data, and unnecessary personal details from saved output. -- **Constructive visibility.** Use only sources the user authorized, preferably for the user’s own work and agreed team visibility. Keep attention on outcomes, context, and collaboration; do not rank coworkers or infer productivity from presence or silence. +## Leave a useful trail -## Run modes +- Prefer the work’s existing artifacts: issue/task/epic, PR, design note, review discussion, test or benchmark result, and status update. +- Keep the useful chain traceable: **intent → decision → change → evidence → outcome**. +- Put important assumptions, decisions, validation, blockers, and remaining uncertainty where the next person will look. +- Do not create a parallel diary or duplicate log by default. If no suitable artifact is writable, include a concise evidence-backed handoff in the normal response. -Support these prompts (or their harness equivalent): +## Think one level above, selectively -- `Run Epi Log for today` — inspect since the last successful run, or the last 24 hours if no state exists. -- `Run Epi Log for the trailing 7 days` — inspect the sliding window ending now, in the configured timezone. +For material work, briefly consider downstream impact, failure modes, maintainability, security, reliability, rollout, rollback, monitoring, validation, and whether a local fix should become reusable prevention. Carry an improvement forward only when it is concrete and worthwhile; do not widen scope for ceremony or polish. -If the user does not specify a mode, run the daily mode. If access, timezone, team expectations, or the canonical ticket/design systems are unknown, ask only the smallest setup question; otherwise run and label the gap. +## Make invisible work legible -## Source handling +Research, debugging, review, design, coordination, decisions, and blocked work count when they produce a conclusion, decision, risk reduction, unblock, reusable artifact, or concrete next action. Do not turn every conversation, thought, or tool call into a log entry. -Use only connected, authorized sources. Prefer source-native filters and stable references over reading whole streams. Typical sources: +## Repair gaps at the point of work -- Git hosting: PRs, revisions, reviews, comments, merge events, checks, and links. -- Ticketing: epics, tasks, status, owner, blockers, and links (GitHub Issues, Jira, Linear, etc.). -- Design docs: ADR/RFC/design documents and the organization’s template or location. -- Communication: bounded Slack/email/drive searches and meeting summaries for explicit decisions, requests, commitments, and blockers. +When a genuine visibility gap is found, make the smallest authorized repair—for example, link an existing PR to its ticket, add missing validation evidence, record a material decision, identify a blocker owner, preserve a rejected alternative, or state what remains unknown. If authorization or access is missing, provide the precise draft or next action instead of silently changing an external system. -Normalize facts internally as: +## Verify and stay honest -`time | source | kind | reference | factual summary | confidence` +Before handoff or completion: -Deduplicate events. Preserve the source reference. Do not claim an event happened merely because another source implies it. +- verify the result with the strongest practical evidence; +- distinguish observed facts, inferences, and `unknown`; +- never claim completion, value, or human review without support; +- state assumptions, blockers, follow-up, and evidence gaps; +- treat missing access as missing evidence, never as “no work.” -If a source is unavailable, continue with the available sources and add an **Evidence gaps** section. Never invent a connector or silently broaden the search. +## Protect constructive visibility -## Checks - -### 1. Delivery and PR flow - -For each relevant PR, record its outcome and current state: opened, updated, review requested, approved, changes requested, checks, merged, closed, or blocked. - -Call a PR **reviewable** when it has one coherent outcome, a bounded risk surface, an understandable description, and a credible validation path. Do not enforce a line-count rule. Suggest a split when the change combines independently releasable outcomes, unrelated risk, or too many review domains. Do not treat a small but valuable fix as a problem. - -“Regular” means a healthy flow of independently reviewable outcomes against the team’s delivery rhythm—not an arbitrary PR quota. If that rhythm is not configured, report the observed gap and ask the team to define it. - -### 2. Human review and real value - -A merge is **human-reviewed** only when the available evidence shows all of the following: - -1. A non-bot human review approval exists. -2. The approval is after the latest relevant revision (or the platform explicitly says it remains valid). -3. The approval is before the merge. - -If any part is not observable, report `unknown`; bot activity never substitutes for human review. Branch protection is useful corroboration, not a reason to guess. - -A PR’s **value evidence** is a link to a user, customer, reliability, security, maintenance, or learning outcome, plus an appropriate validation result. Missing linkage means **value not demonstrated in the available evidence**, not “worthless.” Ask for the smallest missing context. - -### 3. Review participation - -For the trailing seven days, summarize the user’s distinct reviews and separate: - -- approvals; -- substantive comments or questions; -- change requests; -- follow-up discussions resolved. - -A **meaningful review** identifies a concrete risk, question, test/evidence gap, alternative with rationale, or decision. `LGTM`, emoji-only, and autogenerated comments do not qualify by themselves. Compare activity to a configured team expectation only; if there is no expectation, show the evidence and ask for one rather than inventing a target. - -Do not optimize for comment volume. A small number of high-signal reviews can be the correct result. - -### 4. Epic and ticket alignment - -Map changed PRs, commits, discussions, meetings, and explicit commitments to epics/tasks/tickets when the system exposes a link. Show: - -- active or recently changed work; -- blocked or stale items and their next owner/action, when known; -- work with no ticket or epic link; -- commitments with no recorded follow-up. - -Do not create or edit tickets automatically. Suggest a link, status update, or next step for approval. - -### 5. Design and architecture decisions - -For changes that affect behavior, architecture, data, security, operations, or a shared interface, look for the organization’s accepted ADR/RFC/design record and its link from the work item or PR. Discover the convention from repository/org documentation; never invent one. - -If the convention or decision is missing, report the exact gap and suggest a draft outline or canonical location. Do not publish it without approval. - -### 6. Alignment signals beyond code - -From bounded communication and meeting sources, extract only explicit facts: a decision, request, promise, blocker, owner, or due date. Link each to the relevant ticket, PR, epic, or design record when possible. Flag contradictions, forgotten follow-ups, and stale commitments. Do not infer sentiment, effort, or agreement from message volume. - -## Output - -Save to the configured log directory if one exists; otherwise return Markdown. A simple default is `.epi-log/` with `daily/YYYY-MM-DD.md` and `weekly/YYYY-Www.md`. Do not silently rewrite an old entry; mark corrections explicitly. - -### Daily - -```markdown -# Epi Log — YYYY-MM-DD - -## Snapshot -One or two factual sentences; include the window and timezone. - -## Visible wins and outcomes -- What materially changed, with references. - -## PR flow and review -- Reviewability, checks, human-review evidence, and open decisions. - -## Epics, tasks, and commitments -- Linked work, blockers, stale items, and unlinked activity. - -## Decisions and documentation -- Decisions made or needed; ADR/RFC/design evidence. - -## Risks and evidence gaps -- Concrete risk, missing source, or unknown—not a guess. - -## Suggested actions (max 3) -1. **Action** — why, with evidence; owner and “done when”; approval needed? -``` - -### Weekly - -```markdown -# Epi Log — trailing 7 days ending YYYY-MM-DD - -## Visible wins and material outcomes -## PR health and human-review evidence -## Review participation and discussions -## Epic/ticket alignment -## Design and architecture records -## Carry-over risks and commitments -## Suggested actions (max 3) -## Evidence gaps -``` - -Suggestions must be concrete, ranked by impact/urgency, and tied to evidence. Prefer “link PR 123 to ENG-42 and add the validation result” over “improve communication.” Never manufacture an achievement, deficiency, target, or completed action. +- Use only authorized sources and existing team conventions. +- Read and write within the user’s permissions; do not merge, approve, comment, message, publish, or edit external artifacts without authorization. +- Never invent evidence, pad diffs, fragment work artificially, spam comments, fake or rubber-stamp reviews, or manufacture activity. +- Do not optimize for PR count, lines, hours, streaks, rankings, or other shallow proxies. Use metrics as context, never as a verdict. diff --git a/references/audit-mode.md b/references/audit-mode.md new file mode 100644 index 0000000..f36fb86 --- /dev/null +++ b/references/audit-mode.md @@ -0,0 +1,143 @@ +# Epi Log audit mode + +This optional reference preserves the explicit daily and trailing-seven-day review workflow. Read it only when the user asks for a retrospective, audit, or visibility report; it is not required for normal task execution and does not create a duplicate log by default. + +## Non-negotiables + +- **Evidence first.** State observable facts and include a URL, ticket ID, message, document, meeting, or other source reference whenever one exists. +- **Unknown is honest.** Missing access or incomplete data is `unknown`; never turn missing evidence into “no work,” “bad work,” or a guess about intent. +- **Read-only by default.** Never merge or approve a PR, post a comment, send a message, edit a ticket or document, or create a reminder without explicit approval for that exact action. +- **Use metrics as context.** Hours, streaks, commit counts, lines changed, and similar signals are never a verdict about value or performance. Counts are navigation, not scores. +- **Human judgment stays human.** “Enough,” “optimal,” “meaningful,” “valuable,” and the organization’s accepted design format must come from the team or user, not from a made-up universal threshold. +- **Least privilege.** Read only the requested, relevant time window and sources. Treat Slack, email, drive, and meeting data as sensitive. Redact secrets, tokens, customer data, and unnecessary personal details from saved output. +- **Constructive visibility.** Use only sources the user authorized, preferably for the user’s own work and agreed team visibility. Keep attention on outcomes, context, and collaboration; do not rank coworkers or infer productivity from presence or silence. + +## Run modes + +Support these prompts (or their harness equivalent): + +- `Run Epi Log for today` — inspect since the last successful run, or the last 24 hours if no state exists. +- `Run Epi Log for the trailing 7 days` — inspect the sliding window ending now, in the configured timezone. + +If the user does not specify a mode, run the daily mode. If access, timezone, team expectations, or the canonical ticket/design systems are unknown, ask only the smallest setup question; otherwise run and label the gap. + +## Source handling + +Use only connected, authorized sources. Prefer source-native filters and stable references over reading whole streams. Typical sources: + +- Git hosting: PRs, revisions, reviews, comments, merge events, checks, and links. +- Ticketing: epics, tasks, status, owner, blockers, and links (GitHub Issues, Jira, Linear, etc.). +- Design docs: ADR/RFC/design documents and the organization’s template or location. +- Communication: bounded Slack/email/drive searches and meeting summaries for explicit decisions, requests, commitments, and blockers. + +Normalize facts internally as: + +`time | source | kind | reference | factual summary | confidence` + +Deduplicate events. Preserve the source reference. Do not claim an event happened merely because another source implies it. + +If a source is unavailable, continue with the available sources and add an **Evidence gaps** section. Never invent a connector or silently broaden the search. + +## Checks + +### 1. Delivery and PR flow + +For each relevant PR, record its outcome and current state: opened, updated, review requested, approved, changes requested, checks, merged, closed, or blocked. + +Call a PR **reviewable** when it has one coherent outcome, a bounded risk surface, an understandable description, and a credible validation path. Do not enforce a line-count rule. Suggest a split when the change combines independently releasable outcomes, unrelated risk, or too many review domains. Do not treat a small but valuable fix as a problem. + +“Regular” means a healthy flow of independently reviewable outcomes against the team’s delivery rhythm—not an arbitrary PR quota. If that rhythm is not configured, report the observed gap and ask the team to define it. + +### 2. Human review and real value + +A merge is **human-reviewed** only when the available evidence shows all of the following: + +1. A non-bot human review approval exists. +2. The approval is after the latest relevant revision (or the platform explicitly says it remains valid). +3. The approval is before the merge. + +If any part is not observable, report `unknown`; bot activity never substitutes for human review. Branch protection is useful corroboration, not a reason to guess. + +A PR’s **value evidence** is a link to a user, customer, reliability, security, maintenance, or learning outcome, plus an appropriate validation result. Missing linkage means **value not demonstrated in the available evidence**, not “worthless.” Ask for the smallest missing context. + +### 3. Review participation + +For the trailing seven days, summarize the user’s distinct reviews and separate: + +- approvals; +- substantive comments or questions; +- change requests; +- follow-up discussions resolved. + +A **meaningful review** identifies a concrete risk, question, test/evidence gap, alternative with rationale, or decision. `LGTM`, emoji-only, and autogenerated comments do not qualify by themselves. Compare activity to a configured team expectation only; if there is no expectation, show the evidence and ask for one rather than inventing a target. + +Do not optimize for comment volume. A small number of high-signal reviews can be the correct result. + +### 4. Epic and ticket alignment + +Map changed PRs, commits, discussions, meetings, and explicit commitments to epics/tasks/tickets when the system exposes a link. Show: + +- active or recently changed work; +- blocked or stale items and their next owner/action, when known; +- work with no ticket or epic link; +- commitments with no recorded follow-up. + +Do not create or edit tickets automatically. Suggest a link, status update, or next step for approval. + +### 5. Design and architecture decisions + +For changes that affect behavior, architecture, data, security, operations, or a shared interface, look for the organization’s accepted ADR/RFC/design record and its link from the work item or PR. Discover the convention from repository/org documentation; never invent one. + +If the convention or decision is missing, report the exact gap and suggest a draft outline or canonical location. Do not publish it without approval. + +### 6. Alignment signals beyond code + +From bounded communication and meeting sources, extract only explicit facts: a decision, request, promise, blocker, owner, or due date. Link each to the relevant ticket, PR, epic, or design record when possible. Flag contradictions, forgotten follow-ups, and stale commitments. Do not infer sentiment, effort, or agreement from message volume. + +## Output + +Save to the configured log directory if one exists; otherwise return Markdown. A simple default is `.epi-log/` with `daily/YYYY-MM-DD.md` and `weekly/YYYY-Www.md`. Do not silently rewrite an old entry; mark corrections explicitly. + +### Daily + +```markdown +# Epi Log — YYYY-MM-DD + +## Snapshot +One or two factual sentences; include the window and timezone. + +## Visible wins and outcomes +- What materially changed, with references. + +## PR flow and review +- Reviewability, checks, human-review evidence, and open decisions. + +## Epics, tasks, and commitments +- Linked work, blockers, stale items, and unlinked activity. + +## Decisions and documentation +- Decisions made or needed; ADR/RFC/design evidence. + +## Risks and evidence gaps +- Concrete risk, missing source, or unknown—not a guess. + +## Suggested actions (max 3) +1. **Action** — why, with evidence; owner and “done when”; approval needed? +``` + +### Weekly + +```markdown +# Epi Log — trailing 7 days ending YYYY-MM-DD + +## Visible wins and material outcomes +## PR health and human-review evidence +## Review participation and discussions +## Epic/ticket alignment +## Design and architecture records +## Carry-over risks and commitments +## Suggested actions (max 3) +## Evidence gaps +``` + +Suggestions must be concrete, ranked by impact/urgency, and tied to evidence. Prefer “link PR 123 to ENG-42 and add the validation result” over “improve communication.” Never manufacture an achievement, deficiency, target, or completed action. diff --git a/scripts/check-docs.py b/scripts/check-docs.py new file mode 100755 index 0000000..fc3428c --- /dev/null +++ b/scripts/check-docs.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +"""Small dependency-free checks for the portable skill documentation.""" + +from pathlib import Path +from urllib.parse import urlsplit +import re +import sys +from typing import List, Optional + + +ROOT = Path(__file__).resolve().parents[1] +README = ROOT / "README.md" +SKILL = ROOT / "SKILL.md" + + +def local_target(raw: str) -> Optional[Path]: + target = raw.strip().split(" ", 1)[0] + if target.startswith(("http://", "https://", "mailto:", "#")): + return None + path = urlsplit(target).path + if not path: + return None + return (README.parent / path).resolve() + + +def main() -> int: + errors: List[str] = [] + + for path in (README, SKILL, ROOT / "LICENSE", ROOT / "references/audit-mode.md"): + if not path.is_file(): + errors.append(f"missing required file: {path.relative_to(ROOT)}") + + if README.is_file(): + readme = README.read_text(encoding="utf-8") + links = re.findall(r"!?(?:\[[^\]]*\])\(([^)]+)\)", readme) + links += re.findall(r'<(?:img|source)[^>]+src(?:set)?=["\']([^"\']+)', readme) + for raw in links: + target = local_target(raw) + if target is None: + continue + try: + target.relative_to(ROOT) + except ValueError: + errors.append(f"README link escapes repository: {raw}") + continue + if not target.exists(): + errors.append(f"README link target is missing: {raw}") + + if "# Compatibility" not in readme: + errors.append("README is missing the Compatibility section") + + if SKILL.is_file(): + skill = SKILL.read_text(encoding="utf-8") + frontmatter = re.match(r"\A---\n(.*?)\n---\n", skill, re.DOTALL) + if not frontmatter: + errors.append("SKILL.md is missing YAML front matter") + else: + header = frontmatter.group(1) + for field in ("name: epi-log", "description:"): + if field not in header: + errors.append(f"SKILL.md front matter is missing {field}") + if "Run Epi Log for today" in skill or "trailing 7 days" in skill: + errors.append("always-on SKILL.md contains optional audit-mode instructions") + + if errors: + for error in errors: + print(f"error: {error}", file=sys.stderr) + return 1 + + print("docs checks: ok") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())