================================================================================
ERROR LOG — HOW TO USE
================================================================================
This is the ERROR LOG of the three-file system (rules / errors / notes).
Every error encountered gets an entry: symptom -> cause -> fix -> status.

MANDATORY: log FIRST, fix AFTER (enforced by check_errors.py and the
git commit-msg hook). Write the CAUSE before you start fixing — that is the
point of the whole system: if you cannot explain why it broke, you have not
understood it yet.

Statuses (canonical vocabulary): FIXED | PARTIAL | OPEN | MITIGATED | WORKAROUND
  FIXED        the error is gone
  PARTIAL      partially fixed / fix in progress
  OPEN         not fixed yet
  MITIGATED    no real fix, but a safety net / fallback is in place
  WORKAROUND   a workaround is used instead of a proper fix

Tooling (run from this folder):
  python check_errors.py                        validate every entry
  python check_errors.py --add                  scaffold a new entry
  python check_errors.py --has-entry "<AREA>"   gate a fix before applying it
  python check_errors.py --archive-days N       archive old FIXED entries
  python _test_errors.py                        run the tooling's unit tests

================================================================================
EXAMPLE ENTRIES (replace with your own; delete this section header)
================================================================================

[2026-08-05] AREA: payment webhook parser
  ERROR: KeyError: 'amount' on webhook payloads without an amount field
  CAUSE: the payload dict has no 'amount' key; payload['amount'] raises
         instead of defaulting
  FIX: use payload.get('amount', 0) and guard None before .strip()
  STATUS: FIXED.

[2026-08-07] AREA: image resize service timeouts
  ERROR: resize job hangs for >60s on 50MP inputs
  CAUSE: Pillow opens the full image into memory before resizing
  FIX: (pending — use progressive downscaling / streaming resize)
  STATUS: OPEN.

[2026-08-08] AREA: search API rate limit
  ERROR: 429 Too Many Requests on back-to-back queries
  CAUSE: the API throttles requests without gaps; retries were instant
  FIX: added exponential backoff + jitter; fallback backend as safety net
  STATUS: MITIGATED.

[2026-08-09] AREA: CI commit-message gate missing
  ERROR: --no-verify commits slip past the local gate unnoticed
  CAUSE: the CI backstop linted the log but never re-checked the commit message
  FIX: check_errors.py --check-commit + a commit-gate CI job re-run the gate on every push
  STATUS: FIXED.

[2026-08-09] AREA: harness blocker install friction
  ERROR: enabling the --no-verify blockers meant hand-editing shell rc files, settings.json and hooks
  CAUSE: no single installer existed for the four enforcement layers
  FIX: hooks/install.sh - one command installs all of them, idempotently
  STATUS: FIXED.

[2026-08-09] AREA: README CI badges missing
  ERROR: the README header showed no CI status, so pass/fail was invisible at a glance
  CAUSE: badges were a roadmap item but never added
  FIX: shields.io + GitHub workflow badges (CI, checks, release, license, python, deps)
  STATUS: FIXED.

[2026-08-09] AREA: README stale test count
  ERROR: README Quick start said "all 64 should pass" (then 90) while the real
         suite grew; a review quoted the stale "90 unit tests" from the README
  CAUSE: file-listing / quick-start lines never updated when tests were added
  FIX: corrected 64->90 (2026-08-09), then 90->117 after --init added 27 tests;
       first sweep missed two more lines (quick-start + dev section), fixed
       in a follow-up; an expanded sweep now finds zero stale counts
  STATUS: FIXED.

[2026-08-09] AREA: README missing PR-workflow docs
  ERROR: once branch protection blocked direct pushes, the README said nothing about how to ship changes
  CAUSE: the PR-based flow was a side effect of enabling protection, not a documented step
  FIX: added a "Shipping a change (PR workflow)" section to the README
  STATUS: FIXED.

[2026-08-09] AREA: one-command --init adoption missing
  ERROR: adopting the system meant hand-copying templates and the git hook
  CAUSE: no one-command setup existed in check_errors.py
  FIX: check_errors.py --init scaffolds errors/rules/notes, installs the
       commit-msg hook, health-checks the log, and runs the unit tests
  STATUS: FIXED.

[2026-08-09] AREA: community polish missing
  ERROR: no issue/PR templates or security policy, so contributors lack
         guidance and the repo looks younger than its docs
  CAUSE: polish was deferred while core features shipped
  FIX: added bug + feature issue templates, a PR template that enforces
       the AREA-marker discipline, and SECURITY.md
  STATUS: FIXED.

[2026-08-09] AREA: code of conduct missing
  ERROR: GitHub community standards showed no CODE_OF_CONDUCT.md, leaving
         the standards checklist incomplete (health 85%)
  CAUSE: it was simply never added; the repo shipped license + contributing
         + templates but skipped the code of conduct
  FIX: added CODE_OF_CONDUCT.md (Contributor Covenant 2.1, recognized by
       GitHub automatically)
  STATUS: FIXED.

[2026-08-09] AREA: permanent visitor counter missing
  ERROR: GitHub traffic stats only keep 14 days, so there was no
         permanent record of how many people viewed the repo
  CAUSE: no visitor badge was in the README
  FIX: added a visitor-badge.laobi.icu badge (page_id=vartiainen1.
       agent-error-log) to the README badge row; verified the URL
       renders an SVG (visitorbadge.io is defunct - 404 on images)
  STATUS: FIXED.

[2026-08-09] AREA: README companion cross-link
  ERROR: the sibling repo agent-decision-log has no back-link from this README - discoverability is one-way
  CAUSE: verification showed agent-decision-log's README links here, but this README has no Companion section at all
  FIX: added a Companion tool section linking agent-decision-log, mirroring its phrasing
  STATUS: FIXED.

[2026-08-09] AREA: README companion badge
  ERROR: the companion tool is not visible from the README badge row - discoverability relies on the Companion section at the bottom
  CAUSE: the badge row only lists this repo's own metrics; the Companion section sits far down the page
  FIX: added a companion badge to the badge row linking agent-decision-log
  STATUS: FIXED.

[2026-08-09] AREA: AGENTS.md missing CI gate note
  ERROR: AGENTS.md does not mention that CI re-enforces the AREA gate on master - a --no-verify commit looks like a permanent bypass
  CAUSE: the Committing section documents the local hook and harness blockers but predates the CI commit-gate job
  FIX: added a bullet noting the CI backstop re-runs check_errors.py --check-commit on every push to master
  STATUS: FIXED.

[2026-08-09] AREA: README test-count drift guard missing
  ERROR: the README's stated test count can drift from the real suite without anyone noticing - it has happened twice across the pair (90 vs 117; no count at all)
  CAUSE: nothing re-checks the stated count at merge time
  FIX: added _check_readme_count.py + a CI job that fails any push/PR where the README count differs from the suite
  STATUS: FIXED.

[2026-08-09] AREA: _extract_area marker mismatch with hooks (review)
  ERROR: review: Python takes the LAST AREA:/LOG: marker, the shell hooks take the FIRST
  CAUSE: _extract_area uses finditer + marks[-1]; MINIMAL_HOOK and git-commitmsg-hook.sh use grep -m1
  FIX: align _extract_area to the FIRST marker in both repos
  STATUS: OPEN.

[2026-08-09] AREA: badge count artifact in live-page verification
  ERROR: live-page verification reported "6 badges" for the agent-decision-log README; the real count is 8
  CAUSE: the extraction regex only matched img.shields.io URLs, missing the actions badge and the laobi.icu visitor badge
  FIX: recounted via full markdown-image extraction; both repos show 8/8 badges, all 16 endpoints HTTP 200
  STATUS: FIXED.

[2026-08-09] AREA: rules.txt missing LESSONS section
  ERROR: rules.txt has no LESSONS LEARNED section - the distilled lessons were never applied
  CAUSE: --lessons --apply had never been run on this repo's rules.txt
  FIX: applied now via --lessons --apply (5 lessons distilled from 18 entries)
  STATUS: FIXED.

[2026-08-10] AREA: concurrent appends lost entries (L9 lost-update)
  ERROR: two concurrent --add runs silently lost one entry - the last
    writer clobbered the other's insert (read-modify-write race)
  CAUSE: append path was unlocked load -> insert_before_section5 -> write
  FIX: serialized with a cross-process lock file (<log>.lock, atomic
    O_CREAT|O_EXCL, 5s wait, stale-lock recovery) and re-read inside
    the lock before writing
  STATUS: FIXED.

[2026-08-10] AREA: L10 locked-file read crash
  ERROR: load() raised PermissionError on a Windows-locked log file, crashing --check
  CAUSE: bare read_text with no try/except (the exact class lesson 10 fixed in the workspace)
  FIX: wrap the read in try/except OSError, return "" (graceful, never raises)
  STATUS: FIXED

[2026-08-10] AREA: doc - HERE-relative default paths FAQ
  ERROR: FAQ lacks the HERE-relative default-path behavior; scratch users can pollute their real repo logs
  CAUSE: defaults resolve relative to the script location (HERE), not cwd - undocumented
  FIX: added FAQ entry explaining HERE defaults and the --log flag
  STATUS: FIXED.

[2026-08-10] AREA: doc - README release note says push to main, repo uses master
  ERROR: README Development section instructs bumping and pushing to main, but the repo default branch is master
  CAUSE: release.yml watches both master and main; the README PR section and badges all use master
  FIX: changed the release note to say master
  STATUS: FIXED.

[2026-08-10] AREA: unicode stdin double-encoded on Windows - stdout reconfigured, stdin not
  ERROR: a --add entry with unicode AREA text (cafe, em-dash) is written mojibake (cafÃ©) when stdin is piped
  CAUSE: check_errors.py reconfigures sys.stdout to utf-8 but leaves sys.stdin on the locale codepage (cp1252), so piped UTF-8 is decoded as latin-1 then re-encoded
  FIX: added the same reconfigure for sys.stdin; regression test pins a unicode round-trip through the CLI
  STATUS: FIXED.

[2026-08-10] AREA: doc - FAQ documents Windows stdin unicode handling
  ERROR: README FAQ lacks an entry noting piped unicode (caf�, em-dash) is handled on Windows
  CAUSE: the stdin-utf8 fix (PR #23) shipped without a user-facing note
  FIX: added a FAQ entry documenting that stdin is reconfigured to UTF-8 like stdout
  STATUS: FIXED.

[2026-08-10] AREA: code review - missing type hints and dataclasses
  ERROR: external code review scored structure 8/20: no type hints, entries are raw dicts, no exception types
  CAUSE: stdlib-only tools shipped untyped; parse_entries returned dict[str, str] entries
  FIX: full type hints, ErrorEntry dataclass with dict-compat __getitem__ bridge, AgentLogError vocabulary
  STATUS: FIXED.


[2026-08-11] AREA: professional packaging - pyproject, defaults guard, publish flow
  ERROR: professional distribution missing - no pip install, no entry points
  CAUSE: zero-dependency single-file design had no packaging manifest
  FIX: pyproject.toml + console script + installed-mode defaults guard + packaging CI + gated publish
  STATUS: OPEN

================================================================================
5) TO ADD A NEW ENTRY
================================================================================
Copy this template (or run: python check_errors.py --add — it scaffolds
the entry for you and validates the status):

  [YYYY-MM-DD] AREA: <what broke>
    ERROR: <symptom — what went wrong>
    CAUSE: <root cause — write this BEFORE fixing>
    FIX: <what fixed it — fill in after fixing>
    STATUS: FIXED | PARTIAL | OPEN | MITIGATED | WORKAROUND
