车东 Che, Dong

Tue 21 July, 2026

23:21 Docs: CSP nonce + strict-dynamic strategy (#158) + v4.9 PLANDOC entry » Recent Commits to phpman:master
Docs: CSP nonce + strict-dynamic strategy (#158) + v4.9 PLANDOC entry

- docs/01-PRODUCT.md: new §3.2 CSP Strategy — current state, target state,
  transition plan (3-phase), implementation note for nonce sharing
- docs/05-PLAN.md: v4.9 CSP nonce + strict-dynamic entry

Co-Authored-By: Claude Code deepseek-v4-pro <noreply@taotoken.net>

Mon 20 July, 2026

06:46 fix: --status query excludes NOT_FOUND entries from emoji counts » Recent Commits to phpman:master
fix: --status query excludes NOT_FOUND entries from emoji counts

Failed enhancements are now cached as status='not_found' to prevent
retries. The --status count query must filter status='found' to avoid
counting failures as completed enhancements.

Co-Authored-By: Claude <noreply@taotoken.net>
06:36 fix: cache NOT_FOUND on LLM failure to prevent repeated retries » Recent Commits to phpman:master
fix: cache NOT_FOUND on LLM failure to prevent repeated retries

Pages that fail enhancement (LLM returns empty) were not cached,
causing them to be retried every batch run, wasting consecutive
failure quota and killing processes prematurely.

Now failed pages are cached as status='not_found', so the next
run's annotation check correctly skips them. Use --rebuild to
force retry cached failures.

Co-Authored-By: Claude <noreply@taotoken.net>
01:42 fix: preg_match_all called before empty() check in splitHtmlIntoSections » Recent Commits to phpman:master
fix: preg_match_all called before empty() check in splitHtmlIntoSections

The heading regex was defined but preg_match_all was placed AFTER the
first empty($matches) guard, so $matches was always undefined and the
function always returned a single chunk. Also fixed stale variable
references ($tag → $headingText, $positions → $matches).

Co-Authored-By: Claude <noreply@taotoken.net>
01:22 fix: man page heading detection in splitHtmlIntoSections » Recent Commits to phpman:master
fix: man page heading detection in splitHtmlIntoSections

Man pages use <a id="section-NAME"><b>SECTION</b> anchors, not <h1> tags.
Previous regex required only ALL_CAPS <b> content, producing 378 false
positives. Fixed to require <a id="section-" or <a id="sub-" prefix.

Also wired chunked path into batch-enhance.php HTML phase.

Co-Authored-By: Claude <noreply@taotoken.net>
00:39 fix: wire chunked enhancement into batch-enhance.php HTML path » Recent Commits to phpman:master
fix: wire chunked enhancement into batch-enhance.php HTML path

batch-enhance.php called callLLM() directly with full raw HTML,
bypassing enhanceManPageChunked(). Now pages > PHPMAN_ENHANCE_CHUNK_THRESHOLD
(200KB) are automatically split and enhanced in chunks.

Co-Authored-By: Claude <noreply@taotoken.net>

Sun 19 July, 2026

22:45 feat: chunked LLM enhancement for large man pages (>200KB) » Recent Commits to phpman:master
feat: chunked LLM enhancement for large man pages (>200KB)

Pages exceeding PHPMAN_ENHANCE_CHUNK_THRESHOLD (default 200KB) are
automatically split into sections at h1/h2 heading boundaries, each
chunk independently enhanced via callLLM(), then reassembled.

Split strategy (failsafe cascade):
1. h1 section boundaries (NAME, SYNOPSIS, DESCRIPTION, etc.)
2. h2 sub-section boundaries within oversized sections
3. Paragraph/block boundaries (</p>, <br>, </li>, </dd>, etc.)
4. Sentence boundaries ($. + ' ') — last resort, never mid-sentence

Key guarantees:
- Never splits inside <pre>, <table>, <dl> blocks
- Parent heading preserved in every chunk for LLM context
- Failed chunks fall back to original HTML (graceful degradation)
- Each chunk capped at PHPMAN_ENHANCE_MAX_CHARS (32KB)

Co-Authored-By: Claude <noreply@taotoken.net>
16:57 docs: add architectural paradox — data sources are already CLI tools » Recent Commits to phpman:master
docs: add architectural paradox — data sources are already CLI tools

The man/perldoc/info/ri/pydoc3 data sources already have CLI interfaces.
phpMan's web layer (HTML rendering, format negotiation, emoji enhance)
is redundant for LLM Agent use cases. The only irreplaceable value:
TLDR cheatsheets + cross-mode FTS5 search.

Co-Authored-By: Claude <noreply@taotoken.net>
16:43 docs: strategic review — phpMan value in the LLM era (GEO/MCP/SEO ana… » Recent Commits to phpman:master
docs: strategic review — phpMan value in the LLM era (GEO/MCP/SEO analysis)

Key findings from production access log:
- AI bots prefer MCP/markdown over HTML (78-86% structured format choice)
- MCP is GPTBot's #1 format (437 > markdown 413 > html 297)
- Traditional SEO failed — Googlebot only 23 phpMan requests
- LLM emoji enhancement cost: ~¥2,170 total (), marginal value
- phpMan's strategic value shifted: human web viewer → AI agent API

Co-Authored-By: Claude <noreply@taotoken.net>

Wed 15 July, 2026

09:27 fix: deterministic PID file naming for multi-mode parallel batch-enhance » Recent Commits to phpman:master
fix: deterministic PID file naming for multi-mode parallel batch-enhance

Problem: restarting a batch process didn't clean up the old one
because PID file paths weren't derived from the same option combination.
Manual 'rm pidfile && nohup ...' bypassed the startup guard, creating
duplicate processes for the same mode.

Changes:
- buildPidFilePath(mode, format) — canonical path for any option combo
- 15 unique PID files: 5 modes × 3 formats (both/html/md)
- --force flag: auto-kills existing process with same PID file
- --yes also enables auto-cleanup (batch/cron friendly)
- --restart + --mode=man auto-finds /tmp/bm.pid (no need --pid-file)
- Old error message now suggests --force as an option

PID file naming:
  --mode=man                → /tmp/bm.pid
  --mode=man --format=html  → /tmp/bm_html.pid
  --mode=ri  --format=md    → /tmp/br_md.pid
  --pid-file=/custom.pid    → /custom.pid (explicit wins)

Co-Authored-By: Claude <noreply@taotoken.net>
05:03 docs: add batch-enhance.php CLI reference with --status to §2.12.1 » Recent Commits to phpman:master

Tue 14 July, 2026

00:24 docs: extract LLM enhancement + GA analytics to external projects » Recent Commits to phpman:master

Mon 13 July, 2026

21:13 fix: deploy src/ before phpMan.php to avoid transient 500 errors » Recent Commits to phpman:master
19:47 Merge SourceForge upstream (AdSense) + Perl module fix » Recent Commits to phpman:master
19:42 fix: prevent PHP default_socket_timeout from preempting CURLOPT_TIMEOUT » Recent Commits to phpman:master
19:42 fix: allow valid Perl modules with multiple :: in 403 guard » Recent Commits to phpman:master
19:42 Increase LLM timeout: primary 120→600s, fallback default 60→300s » Recent Commits to phpman:master
19:42 Add runtime process status to --status output » Recent Commits to phpman:master
19:42 Add LLM gateway failure analysis report » Recent Commits to phpman:master
19:42 Add /status JSON endpoint for batch enhance process monitoring » Recent Commits to phpman:master