{"id":51581156,"url":"https://github.com/dd3ok/briefprint","last_synced_at":"2026-07-11T06:30:53.182Z","repository":{"id":357031700,"uuid":"1235025511","full_name":"dd3ok/briefprint","owner":"dd3ok","description":"Read once. Brief anywhere. Reusable document briefings from fingerprinted cache.","archived":false,"fork":false,"pushed_at":"2026-07-04T13:12:48.000Z","size":372,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-04T13:18:43.025Z","etag":null,"topics":["agent-skill","codex-skill","document-summarization","llm-caching","openai-skill","python"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dd3ok.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-11T00:00:03.000Z","updated_at":"2026-07-04T13:12:52.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dd3ok/briefprint","commit_stats":null,"previous_names":["dd3ok/document-briefing-cache-skill","dd3ok/briefprint"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dd3ok/briefprint","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dd3ok%2Fbriefprint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dd3ok%2Fbriefprint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dd3ok%2Fbriefprint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dd3ok%2Fbriefprint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dd3ok","download_url":"https://codeload.github.com/dd3ok/briefprint/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dd3ok%2Fbriefprint/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35353668,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-11T02:00:05.354Z","response_time":104,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-skill","codex-skill","document-summarization","llm-caching","openai-skill","python"],"created_at":"2026-07-11T06:30:52.968Z","updated_at":"2026-07-11T06:30:53.173Z","avatar_url":"https://github.com/dd3ok.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Briefprint\n\n[![Python](https://img.shields.io/badge/Python-3.10%2B-blue?logo=python\u0026logoColor=white)](https://www.python.org/)\n[![License](https://img.shields.io/github/license/dd3ok/briefprint)](https://github.com/dd3ok/briefprint/blob/main/LICENSE)\n[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/dd3ok/briefprint/ci.yml?branch=main)](https://github.com/dd3ok/briefprint/actions/workflows/ci.yml)\n\nRead once. Brief anywhere.\n\n[English](README.md) | [한국어](README.ko.md)\n\nBriefprint packages the `briefprint` agent skill and Python runtime for repeated document briefing work.\n\nIt turns documents into reusable structured briefings, caches them by document fingerprint, and renders new formats from the cached state instead of asking an LLM to re-read the same content.\n\n```text\ndocument-like input\n  -\u003e normalize to DocumentInput\n  -\u003e fingerprint the content\n  -\u003e summarize cache misses into DocumentSummaryState\n  -\u003e render brief / digest / executive / action items / debug\n```\n\n## What It Solves\n\nMost summarization workflows pay again every time the user asks for a slightly different answer.\n\n```text\n\"summarize this\"          -\u003e LLM reads the whole document\n\"make it shorter\"        -\u003e LLM reads the whole document again\n\"make it Slack-friendly\" -\u003e LLM reads the whole document again\n\"add this one update\"    -\u003e LLM may read everything again\n```\n\nBriefprint changes the boundary. The expensive step is document understanding. Once a document has a `DocumentSummaryState`, repeated render requests can reuse it.\n\n```text\nfirst run on changed documents -\u003e summarize cache misses\nsame document set              -\u003e rendered-output cache hit\nnew render mode                -\u003e template render from cached document state\none new update                 -\u003e summarize only the new document\n```\n\nThis is not a semantic cache. It is an exact document-summary cache, which is safer for IDs, dates, metrics, incident logs, tickets, and reports where stale or approximate answers are unacceptable.\n\n## Quick Start\n\nInstall the Python runtime:\n\n```bash\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -e \".[dev]\"\n```\n\nRequires Python \u003e=3.10. If your shell provides `python`, use it after the virtual environment is activated.\n\nOptional extras:\n\n```bash\npip install -e \".[llm]\"  # OpenAI-backed structured summarizer\npip install -e \".[pdf]\"  # PDF text extraction helpers\n```\n\nNaming note:\n\n- Agent skill: `briefprint`\n- Python package/CLI: `document-briefing-cache` / `document_briefing_cache`\n\nThe runtime names are kept for package compatibility while the installable agent skill is branded as Briefprint.\n\nRun the sample:\n\n```bash\npython -m document_briefing_cache.cli run \\\n  --input examples/mixed_documents.json \\\n  --mode brief \\\n  --cache-dir .cache/briefprint \\\n  --summary-mode rules \\\n  --show-stats \\\n  --explain-cache\n```\n\nRun the same command again. Repeated content should not call the summarizer:\n\n```text\nsummarizer_calls: 0\n```\n\nRender another format from the same cached document state:\n\n```bash\npython -m document_briefing_cache.cli run \\\n  --input examples/mixed_documents.json \\\n  --mode action_items \\\n  --cache-dir .cache/briefprint \\\n  --summary-mode rules \\\n  --show-stats\n```\n\n## Agent Skill Install\n\nFor Codex, Claude Code, Gemini CLI, Antigravity, OpenClaw, Hermes, or another agent host, install only the lightweight skill bundle:\n\n```text\nskills/briefprint/\n  SKILL.md\n  agents/openai.yaml\n  references/*.md\n```\n\nDo not install the repository root as an agent skill. Root-copy installers can include tests, docs, examples, evals, source code, and validation scripts. See [docs/agent-skill-installation.md](docs/agent-skill-installation.md).\n\nBriefprint is explicit-use by design. For Codex, use `$briefprint`; for Claude Code, use `/briefprint`; for other hosts, use the host's explicit skill invocation or the CLI when you want reusable cached document briefings. Ordinary one-off summaries should not trigger the skill automatically.\n\nClaude.ai description variant: Explicit-use cached briefings for supplied documents, notes, logs, tickets, reports, JSON/XML, or transcripts. Use for repeated summaries, rerendering, digests, actions, risks, or metrics.\n\n## Benchmark Receipts\n\nThis local benchmark was run on the current examples with the deterministic `rules` summarizer:\n\n```bash\npython -m document_briefing_cache.cli benchmark \\\n  --input examples/mixed_documents.json \\\n  --incremental-input examples/incident_update.json \\\n  --cache-dir .cache/briefprint/readme-benchmark \\\n  --fresh \\\n  --mode brief \\\n  --mode digest \\\n  --mode executive \\\n  --mode action_items \\\n  --json\n```\n\n| Measure | Result |\n|---|---:|\n| Scenarios | 7 |\n| Base documents | 3 |\n| Combined documents after update | 4 |\n| Naive re-summarization input tokens estimate | 1,748 |\n| Cache-aware cache-miss input tokens estimate | 309 |\n| Estimated tokens saved | 1,439 |\n| Estimated savings | 82.32% |\n| Total summarizer calls | 4 |\n| Document cache hits | 16 |\n| Document cache misses | 4 |\n\nScenario shape:\n\n| Scenario | Summarizer calls | Cache-miss input tokens |\n|---|---:|---:|\n| Cold brief over 3 documents | 3 | 226 |\n| Same brief again | 0 | 0 |\n| Rerender digest | 0 | 0 |\n| Rerender executive | 0 | 0 |\n| Rerender action items | 0 | 0 |\n| Add one update | 1 | 83 |\n| Rerender debug over combined set | 0 | 0 |\n\nRows with `0` summarizer calls and `0` cache-miss input tokens are intentional: they show that rerenders and repeated briefs reuse cached structured state instead of re-reading unchanged documents.\n\nHonest number warning: these are deterministic local estimates from the benchmark harness, not provider billing telemetry. Use OpenAI/provider usage or host telemetry when exact billing matters. The benchmark also includes lightweight quality smoke checks for obvious actions, decisions, risks, and metrics; it is not a semantic accuracy score.\n\n## When It Helps\n\n- Repeated briefs over the same tickets, incident reports, meeting notes, logs, or PR summaries.\n- Rendering one source into several outputs: executive memo, Slack digest, action list, risk report, debug view.\n- Incremental feeds where one new item is appended and older items keep stable IDs.\n- Agent workflows where the same source needs to be reused across several turns.\n\n## When It Does Not Help Much\n\n- One-off documents that will never be reused.\n- Documents that are rewritten wholesale each time.\n- Inputs with unstable section IDs or reordered sections, unless you pass structured records with stable IDs.\n- Requests that require fresh external facts, policy changes, current prices, or live news.\n\n## Limits And Alternatives\n\nBriefprint is intentionally not a broad DLP scanner, URL crawler, RAG framework, or provider billing profiler.\n\nCurrent limits:\n\n- PII redaction is basic. `basic-contact-v2` covers common email addresses, Korean mobile formats such as `010-1234-5678`, `010 1234 5678`, `01012345678`, and `010.1234.5678`, US phone numbers, and common dashed Korean resident or foreigner registration number patterns. Korean names, Kakao or Naver account IDs, addresses, and bank account numbers remain out of scope.\n- The default `rules` summarizer is deterministic shallow extraction. It is useful for cache demos and smoke checks, not semantic summary quality.\n- Cache files are plaintext JSON. HMAC detects tampering; it does not encrypt contents.\n- CLI inputs are local files. Remote URLs should be fetched by the caller and passed as local files or normalized payloads.\n- The JSON cache uses atomic replacement for writes but has no cross-process file lock. Avoid sharing one cache directory across concurrent writers unless you add external locking.\n- The built-in CLI LLM adapter is OpenAI-only. Python callers can provide another `BaseSummarizer` implementation for Anthropic, Gemini, or an internal model.\n- Benchmark token savings are local estimates from the harness, not provider billing telemetry.\n\nAlternative boundaries:\n\n- LangChain CacheBackedEmbeddings caches embedding calculations by text hash. It is useful when embedding recomputation is the expensive step, but it is not a structured document-summary cache and does not provide Briefprint's rerenderable `DocumentSummaryState`.\n- LlamaIndex `IngestionPipeline` with a docstore is a broader ingestion/RAG pipeline with transformation caches and document hash tracking. Use it when you need indexing and retrieval; Briefprint stays smaller for repeated briefing renders.\n- OpenAI or Anthropic provider prompt caching is complementary. Provider prompt caching can reduce repeated prompt-prefix processing cost; Briefprint can avoid cache-hit document summarizer calls entirely.\n- A custom Redis plus SHA256 cache can be flexible, but you need to design schema versioning, redaction-policy keying, evidence validation, TTLs, and render keys yourself.\n\n## Input Scope\n\nThe CLI `--input` option currently accepts local file path values. It does not fetch URLs such as `http://` or `https://`.\n\nURL-bearing metadata inside JSON, XML, HTML, or `DocumentInput.source` is preserved as source/reference metadata for evidence and rendering. To summarize remote content, fetch it outside this tool and pass the saved local file or normalized payload.\n\n## Modes\n\n| Mode | Use |\n|---|---|\n| `brief` | Standard multi-document briefing |\n| `executive` | Concise decision-maker summary |\n| `action_items` | Owners, deadlines, follow-ups |\n| `digest` | Chat-friendly short digest |\n| `debug` | Parsed summaries, evidence, and cache stats |\n\n## Cache And Privacy\n\nRecommended defaults:\n\n- keep repo-local cache under `.cache/briefprint` and keep it out of version control,\n- keep `document_summaries` as a short TTL cache for repeated documents,\n- keep `rendered_outputs` shorter-lived because template rendering is cheap,\n- run pruning during normal use with `--prune-on-start`,\n- use `ephemeral` for sensitive one-off work.\n\n```bash\npython -m document_briefing_cache.cli run \\\n  --input examples/mixed_documents.json \\\n  --cache-dir .cache/briefprint \\\n  --cache-policy ttl \\\n  --document-ttl 7d \\\n  --output-ttl 24h \\\n  --prune-on-start\n```\n\nBriefprint does not run a background cleanup daemon. TTL values mark cache entries as expired; physical deletion happens when you run `cache prune`, enable `--prune-on-start` or `--prune-on-exit`, or use a delete-on-exit policy. This follows the common local-tooling pattern: generated caches are disposable, ignored by Git, and cleaned explicitly or opportunistically during tool runs. CI caches are the main exception; platforms such as GitHub Actions apply their own last-access and size eviction policies.\n\nUse longer retention only when the cache is intentionally persistent:\n\n- project-local default: `.cache/briefprint`, `--document-ttl 7d`, `--output-ttl 24h`, `--prune-on-start`,\n- sensitive one-off work: `--sensitive`,\n- long-lived shared cache: explicit `--cache-policy persistent` or a longer `--document-ttl`.\n\nSkill bundle and runtime cache are separate. The skill bundle is static install-time guidance; the runtime cache lives under `--cache-dir` and is owned by the Briefprint CLI/runtime. Installing, updating, or removing the agent skill does not migrate, prune, or delete runtime caches. No portable agent-skill host contract currently provides automatic eviction for generated document state, so do not write document caches into the installed skill directory.\n\nFor sensitive documents:\n\n```bash\nexport DBC_CACHE_HMAC_SECRET=\"replace-with-a-local-secret\"\npython -m document_briefing_cache.cli run \\\n  --input sensitive.json \\\n  --sensitive \\\n  --cache-hmac-secret-env DBC_CACHE_HMAC_SECRET\n```\n\nFor sensitive documents, the safe default is no persistent cache. `--sensitive` is a convenience alias for `--cache-policy ephemeral --no-output-cache --redact-pii --delete-on-exit created`.\n\n`--redact-pii` applies the built-in `basic-contact-v2` profile before cache misses are summarized. It covers common email addresses, Korean mobile numbers, common dashed Korean resident or foreigner registration number patterns, and US phone numbers. It is not a complete PII detector.\n\n`--redact-secrets` applies the built-in `basic-secrets-v1` profile. It is best-effort and targets bearer tokens, API keys, webhook URLs, card-like values, and string values under secret-shaped JSON keys. Secret redaction is not included in --sensitive; enable it explicitly when secret-shaped values may appear.\n\n`--redact-secrets` may also remove operational correlation values such as `session_id` when they appear under secret-shaped keys. Enable it when secret protection matters more than exact operational correlation.\n\n`--cache-hmac-secret-env` signs cache envelopes with HMAC-SHA256. HMAC is tamper detection only, not encryption. Use encrypted storage, tmpfs, or another encrypted backend when cache contents need confidentiality.\n\nCache maintenance:\n\n```bash\npython -m document_briefing_cache.cli cache stats --cache-dir .cache/briefprint --json\npython -m document_briefing_cache.cli cache prune --cache-dir .cache/briefprint --older-than 7d --dry-run --json\npython -m document_briefing_cache.cli cache clear --cache-dir .cache/briefprint --layer rendered_outputs --yes\n```\n\n## LLM Summarizer\n\nThe default `rules` summarizer is local, deterministic, and token-free. It is useful for demos, cache validation, and shallow extraction.\n\nFor high-quality summaries of new documents, connect an LLM summarizer at the cache-miss step and keep the output structured as `DocumentSummaryState`.\n\n```bash\nOPENAI_API_KEY=\"...\" python -m document_briefing_cache.cli run \\\n  --input examples/mixed_documents.json \\\n  --summary-mode openai \\\n  --openai-model gpt-4.1-mini \\\n  --llm-timeout 60 \\\n  --llm-max-retries 2 \\\n  --llm-max-input-tokens 12000 \\\n  --llm-max-output-tokens 4000 \\\n  --cache-dir .cache/briefprint \\\n  --show-stats\n```\n\nPrivacy note: LLM-backed summarizers send cache misses to the configured provider. Cache directories are plaintext JSON and may persist structured summaries, names, IDs, dates, metrics, evidence quotes, sources, and rendered outputs.\n\n## Validate\n\n```bash\npython -m pytest -q\npython scripts/validate_skill.py\npython scripts/validate_skill.py --run-evals\n```\n\n`--run-evals` executes compact briefing evals with structured-state assertions for actions, risks, metrics, and evidence. It also checks `trigger_eval_cases.json` as static boundary fixtures. Trigger evals validate intended trigger coverage and near-miss cases; they do not measure actual model-side invocation behavior.\n\n`evals/model_invocation_benchmark_cases.json` is a manual benchmark worksheet for hosts that expose real skill invocation telemetry. It is schema-validated, but CI does not claim to measure model-side routing.\n\n## Repository Map\n\n```text\nskills/briefprint/                 installable agent skill\nsrc/document_briefing_cache/        Python runtime and CLI\nsrc/document_briefing_cache/templates/\n                                    render templates\nexamples/                           sample inputs and demos\nevals/                              compact eval and benchmark fixtures\nreferences/                         architecture, schema, LLM contract, roadmap\ndocs/agent-skill-installation.md     host-specific install notes\ntests/                              unit and behavior tests\nscripts/validate_skill.py           repository validation\n```\n\n## Further Reading\n\n- [README.ko.md](README.ko.md)\n- [docs/agent-skill-installation.md](docs/agent-skill-installation.md)\n- [references/architecture.md](references/architecture.md)\n- [references/schema.md](references/schema.md)\n- [references/llm-contract.md](references/llm-contract.md)\n- [references/best-practices.md](references/best-practices.md)\n- [references/competitive-roadmap.md](references/competitive-roadmap.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdd3ok%2Fbriefprint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdd3ok%2Fbriefprint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdd3ok%2Fbriefprint/lists"}