@ictechgy/context-guard 0.4.14 → 0.4.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.ko.md +72 -1
- package/README.md +85 -2
- package/docs/benchmark-fixtures/image-context-pack-full-evidence.prompt.example.md +28 -0
- package/docs/benchmark-fixtures/image-context-pack-packed-evidence.prompt.example.md +31 -0
- package/docs/benchmark-fixtures/image-context-pack.evidence.example.jsonl +2 -0
- package/docs/benchmark-fixtures/image-context-pack.tasks.example.json +18 -0
- package/docs/benchmark-fixtures/image-context-pack.variants.example.json +10 -0
- package/docs/benchmark-workflow-examples.md +16 -0
- package/docs/experimental-benchmark-fixtures.md +52 -1
- package/package.json +2 -1
- package/plugins/context-guard/.claude-plugin/plugin.json +1 -1
- package/plugins/context-guard/README.ko.md +43 -0
- package/plugins/context-guard/README.md +43 -0
- package/plugins/context-guard/bin/context-guard-artifact +90 -9
- package/plugins/context-guard/bin/context-guard-audit +169 -66
- package/plugins/context-guard/bin/context-guard-bench +7038 -307
- package/plugins/context-guard/bin/context-guard-compress +90 -8
- package/plugins/context-guard/bin/context-guard-diet +1 -7
- package/plugins/context-guard/bin/context-guard-experiments +3085 -134
- package/plugins/context-guard/bin/context-guard-failed-nudge +705 -83
- package/plugins/context-guard/bin/context-guard-guard-read +490 -55
- package/plugins/context-guard/bin/context-guard-mcp +999 -0
- package/plugins/context-guard/bin/context-guard-pack +744 -20
- package/plugins/context-guard/bin/context-guard-read-symbol +7 -2
- package/plugins/context-guard/bin/context-guard-rewrite-bash +2204 -223
- package/plugins/context-guard/bin/context-guard-sanitize-output +560 -85
- package/plugins/context-guard/bin/context-guard-setup +1073 -147
- package/plugins/context-guard/bin/context-guard-statusline +131 -54
- package/plugins/context-guard/bin/context-guard-statusline-merged +7 -3
- package/plugins/context-guard/bin/context-guard-tool-prune +44 -11
- package/plugins/context-guard/bin/context-guard-trim-output +89 -13
- package/plugins/context-guard/brief/README.md +19 -0
- package/plugins/context-guard/brief/narration-mode.quiet.md +21 -0
- package/plugins/context-guard/lib/context_guard_commands.py +14 -2
- package/plugins/context-guard/lib/credential_policy.py +177 -0
- package/plugins/context-guard/lib/transcript_usage_reducer.py +378 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Experimental benchmark fixtures
|
|
2
2
|
|
|
3
|
-
These fixtures are **fixture-only** starter scaffolds for future visual/OCR, learned-compression, reversible output-transform, and token-savings roadmap experiments. They are **synthetic**, package-visible examples for `context-guard-bench` task and variant shapes; they are **not shipped benchmark results**, not OCR/compression implementations, not cache/tool-deferral implementations, and not hosted API savings claims.
|
|
3
|
+
These fixtures are **fixture-only** starter scaffolds for future image-context-pack, visual/OCR, learned-compression, reversible output-transform, and token-savings roadmap experiments. They are **synthetic**, package-visible examples for `context-guard-bench` task and variant shapes; they are **not shipped benchmark results**, not image packing/OCR/compression implementations, not cache/tool-deferral implementations, and not hosted API savings claims.
|
|
4
4
|
|
|
5
5
|
Use them when designing an experiment that starts from ContextGuard's existing benchmark discipline:
|
|
6
6
|
|
|
@@ -35,15 +35,66 @@ The included token-savings evidence file is deliberately `synthetic_fixture` pro
|
|
|
35
35
|
|
|
36
36
|
This runner-native swap only proves command shape and prompt selection until the user supplies real sanitized tasks, success checks, and provider telemetry. It does **not** make dry-run output, artifact receipts, byte counts, or digest metadata into token/cost savings evidence. For real non-dry-run output-transform experiments, keep task IDs matched across baseline and digest variants and require provider-measured primary token/cost fields on matched successful tasks before making any comparison claim.
|
|
37
37
|
|
|
38
|
+
## Optional image-context evaluation profile
|
|
39
|
+
|
|
40
|
+
`context-guard-bench` supports an optional, versioned evaluation profile for image-context-pack replays. A task opts in with `"evaluation_profile": "contextguard.bench.image-context-pack-evaluation.v1"`, and every evidence row for that task repeats the same value plus an `evaluation_controls` block. Absence means today's generic behavior: a fixture, report, or workflow that does not opt in acquires no new required field and no changed claim decision.
|
|
41
|
+
|
|
42
|
+
The profile is **evaluation-only**. It makes imported image-context evidence machine-reviewable; it adds no image renderer, OCR engine, image parser, provider client or SDK, credential handling, network access, proxy, daemon, subprocess transformer, automatic context omission, replacement runtime, or hosted savings claim. **Operators own the real work**: provider runs, images, credentials, and corpus selection stay with you. The runner only validates the evidence you import, and only against local, bounded checks.
|
|
43
|
+
|
|
44
|
+
`evaluation_controls` carries bounded, typed fields:
|
|
45
|
+
|
|
46
|
+
- `prompt_evidence` — SHA-256 of the selected variant prompt file plus a sanitized source label. The runner recomputes the hash with the existing no-follow bounded reader and compares it.
|
|
47
|
+
- `source_omission` — whether any source text was omitted or transformed for this variant.
|
|
48
|
+
- `exact_text_fallback` — receipt ID, content SHA-256, exact local retrieval command, and a bounded projection of one imported proof-verifier result. Required when `source_omission.present=true`. The runner labels this `imported_local_verifier_attestation`: it checks that the record is internally consistent and binds the same receipt/hash/command, but it does **not** authenticate who produced the record and does **not** reread the artifact.
|
|
49
|
+
- `protected_zone_review` — `deny` policy, explicit review completion, zero included protected or prompt-like regions, reviewer/source label, and a review note. This is a human/tool attestation, not semantic proof.
|
|
50
|
+
- `missed_context_review` — completion flag, presence flag, bounded summary, and correction-required flag.
|
|
51
|
+
- `human_correction` — count and bounded reason; the count must equal the existing top-level `corrections` field.
|
|
52
|
+
- `provider_usage` and `shifted_cost` — measurement flags that must agree with the generic normalized fields. Lane metadata can never upgrade an unmeasured value into a measured one.
|
|
53
|
+
- `control_provenance` — bounded local verifier/review identifiers, kept separate from provider-export provenance.
|
|
54
|
+
|
|
55
|
+
Every string, array, and nested block is bounded, and unknown keys are rejected for v1 so a typo cannot become a false pass. Schema evolution requires a new profile version.
|
|
56
|
+
|
|
57
|
+
### Rejected before write versus accepted and blocked
|
|
58
|
+
|
|
59
|
+
Evidence that cannot be interpreted safely or unambiguously is **rejected before anything is written** — no CSV, ledger, report, dashboard, or lock sidecar is created. Evidence that is well-formed but negative is **accepted and scored as blocked**, so a reviewer can still read why it failed.
|
|
60
|
+
|
|
61
|
+
| Evidence condition | Outcome |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| Missing control block; wrong type, oversize, unknown v1 key or version; task/row profile mismatch; duplicate, mixed, or partial profile batch | rejected before write |
|
|
64
|
+
| `--resume`, or a pre-existing non-empty CSV, for a profiled replay | rejected before write |
|
|
65
|
+
| Missing or unsafe prompt mapping, or a prompt SHA mismatch | rejected before write |
|
|
66
|
+
| Correction counts or measurement flags that contradict the generic fields | rejected before write |
|
|
67
|
+
| A fallback record that claims verification while its own schema, status, blockers, replacement, receipt, hash, or command fields contradict that claim | rejected before write |
|
|
68
|
+
| Explicitly unverified or failed fallback; non-`deny`, incomplete, or unknown protected-zone review; reported missed context; explicitly unmeasured provider or shifted cost; correction-burden or failure-rate regression | accepted, lane blocked |
|
|
69
|
+
|
|
70
|
+
Errors are bounded and redacted: raw prompts, prompt paths, artifact directories, receipt contents, and secret-shaped values are never echoed. In v1 a profiled replay requires a fresh empty CSV and a complete baseline/candidate batch. Incremental replay is deliberately given up so profile context cannot silently vanish from a resumed or pre-existing report.
|
|
71
|
+
|
|
72
|
+
### Status ceiling
|
|
73
|
+
|
|
74
|
+
A profiled report exposes `evaluation_profiles.image_context_pack` with `status: blocked` or `status: ready_for_bounded_pilot_review`.
|
|
75
|
+
|
|
76
|
+
**`ready_for_bounded_pilot_review` is the ceiling, and it is not an achievement.** It is not promotion, not runtime authority, not quality proof, and not a hosted API token/cost savings claim. It means only that the imported evidence was complete and internally consistent enough to justify a bounded human pilot review.
|
|
77
|
+
|
|
78
|
+
For any profiled report the runner clamps every public-authority surface: `evaluation_only=true`, `promotion_authority=false`, `public_claim_allowed=false`, top-level `public_claim_eligible=false`, `public_claim_status` and legacy `claim_status` set to the stable non-candidate value `image_context_pack_evaluation_only_not_public_claim`, generic `public_claim_readiness.claim_allowed=false`, and profiled matched-pair `token_savings_claim_allowed` and `shifted_cost_claim_allowed` false. Pre-clamp measurements survive only in explicitly non-authoritative fields such as `raw_metric_claim_status`. The report also carries a `sample_adequacy` observation with matched counts and `policy_status: not_defined_for_promotion`: this feature defines no sample-size or promotion threshold, and a future consensus decision must.
|
|
79
|
+
|
|
38
80
|
## Included fixture sets
|
|
39
81
|
|
|
40
82
|
| Fixture set | Task file | Variant file | Evidence replay file | Intended future experiment |
|
|
41
83
|
| --- | --- | --- | --- | --- |
|
|
84
|
+
| Matched image-context-pack correction | [`benchmark-fixtures/image-context-pack.tasks.example.json`](benchmark-fixtures/image-context-pack.tasks.example.json) | [`benchmark-fixtures/image-context-pack.variants.example.json`](benchmark-fixtures/image-context-pack.variants.example.json) | [`benchmark-fixtures/image-context-pack.evidence.example.jsonl`](benchmark-fixtures/image-context-pack.evidence.example.jsonl) | Replay one full sanitized textual baseline against one synthetic packed textual variant that succeeds only after one recorded human correction, without turning byte proxies into a hosted claim. |
|
|
42
85
|
| Visual/OCR evidence | [`benchmark-fixtures/visual-ocr.tasks.example.json`](benchmark-fixtures/visual-ocr.tasks.example.json) | [`benchmark-fixtures/visual-ocr.variants.example.json`](benchmark-fixtures/visual-ocr.variants.example.json) | n/a | Compare full visual evidence against cropped or OCR-derived evidence after the user supplies sanitized textual evidence, missed-context notes, crop/OCR telemetry, and provider telemetry. |
|
|
43
86
|
| Learned compression | [`benchmark-fixtures/learned-compression.tasks.example.json`](benchmark-fixtures/learned-compression.tasks.example.json) | [`benchmark-fixtures/learned-compression.variants.example.json`](benchmark-fixtures/learned-compression.variants.example.json) | n/a | Compare sanitized baseline context packs against a fixture-only compressed digest candidate after exact retrieval or receipt fallback, quality gates, and shifted costs are measured. |
|
|
44
87
|
| Reversible output transform | [`benchmark-fixtures/output-transform.tasks.example.json`](benchmark-fixtures/output-transform.tasks.example.json) | [`benchmark-fixtures/output-transform.variants.example.json`](benchmark-fixtures/output-transform.variants.example.json) | n/a | Compare raw sanitized command output against a digest plus artifact receipt after variant prompt files, success checks, and provider telemetry are supplied. |
|
|
45
88
|
| Token-savings 12-task roadmap | [`benchmark-fixtures/token-savings-12task.tasks.example.json`](benchmark-fixtures/token-savings-12task.tasks.example.json) | [`benchmark-fixtures/token-savings-12task.variants.example.json`](benchmark-fixtures/token-savings-12task.variants.example.json) | [`benchmark-fixtures/token-savings-12task.evidence.example.jsonl`](benchmark-fixtures/token-savings-12task.evidence.example.jsonl) | Exercise a canonical 12-task spread for bugfix, exploration, review, log analysis, migration, docs, refactor, performance, telemetry, cache layout, tool-schema deferral, and artifact receipt experiments after real success commands and provider telemetry are supplied. |
|
|
46
89
|
|
|
90
|
+
## Matched image-context-pack correction fixture notes
|
|
91
|
+
|
|
92
|
+
The image-context-pack fixture is a deterministic replay over one task and two variants. The baseline supplies full sanitized textual evidence. The packed variant explicitly records that qualifying context was omitted at first, then records one **synthetic human correction** and retains the missed-context disclosure. Its full-text fallback is narrative/shape only and remains `verified=false`; the fixture does not retrieve an artifact or prove that the initial pack was complete.
|
|
93
|
+
|
|
94
|
+
Both rows are plan-only, use protected-zone deny, and describe byte counts only as sanitized textual UTF-8 proxies—not image bytes or provider tokens. The fixture performs no renderer, OCR, image-parser, provider, model, network, or subprocess call; ships no replacement or runtime; and makes no hosted claim. A successful synthetic replay after one correction does not establish quality non-inferiority, token savings, or cost savings.
|
|
95
|
+
|
|
96
|
+
The fixture opts into the image-context evaluation profile described above, so its known-negative evidence exercises the blocked path rather than the rejection path: the unverified fallback (`verified=false`) and the one recorded correction produce an explicitly **blocked** lane score with stable blocker IDs, not a parse failure and not a claim. It is a worked example of what negative-but-reviewable evidence looks like. Because it is provider-unmeasured synthetic evidence, it cannot reach `ready_for_bounded_pilot_review` no matter how its nested metadata is written.
|
|
97
|
+
|
|
47
98
|
## Visual/OCR fixture notes
|
|
48
99
|
|
|
49
100
|
The visual/OCR fixtures describe sanitized textual visual evidence only and now demonstrate `variant_prompt_files` for full visual evidence versus cropped/OCR-derived evidence. They do not include image assets, crop images, run OCR, prune visual tokens, or call a model. Future experiments should record image dimensions, crop area, visible area, omitted or missed context, OCR confidence/error notes, full visual fallback conditions, provider image/text token telemetry when available, task success, corrections, and any external/local processing cost.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ictechgy/context-guard",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.16",
|
|
4
4
|
"description": "ContextGuard CLI helpers for keeping AI coding agent context focused and local-first.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/ictechgy/context-guard#readme",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"context-guard-pack": "plugins/context-guard/bin/context-guard-pack",
|
|
26
26
|
"context-guard-tool-prune": "plugins/context-guard/bin/context-guard-tool-prune",
|
|
27
27
|
"context-guard-compress": "plugins/context-guard/bin/context-guard-compress",
|
|
28
|
+
"context-guard-mcp": "plugins/context-guard/bin/context-guard-mcp",
|
|
28
29
|
"context-guard-bench": "plugins/context-guard/bin/context-guard-bench",
|
|
29
30
|
"context-guard-read-symbol": "plugins/context-guard/bin/context-guard-read-symbol",
|
|
30
31
|
"context-guard-rewrite-bash": "plugins/context-guard/bin/context-guard-rewrite-bash",
|
|
@@ -79,6 +79,7 @@ context-guard-sanitize-output -- rg -n "TOKEN|SECRET" .
|
|
|
79
79
|
context-guard-sanitize-output -- git diff
|
|
80
80
|
context-guard-pack auto --root . --query "failing tests review" --diff HEAD --manifest-out suggested-pack.json --pack-out context-pack.md --budget-bytes 12000 --json --explain --adaptive-k --adaptive-k-policy recall
|
|
81
81
|
context-guard-pack build --root . --manifest suggested-pack.json --budget-bytes 12000 --json
|
|
82
|
+
context-guard-pack build --root . --manifest suggested-pack.json --budget-bytes 12000 --json --no-artifact --delta-from-pack-id 0123456789abcdef0123
|
|
82
83
|
context-guard-pack slice --root . --path README.md --lines 1:40 --json
|
|
83
84
|
context-guard-cache-score --input prompt.json --provider openai --json
|
|
84
85
|
context-guard-tool-prune select --catalog tools.json --query "review failing tests" --top 5 --budget-bytes 12000 --json
|
|
@@ -90,6 +91,10 @@ context-guard-statusline-merged
|
|
|
90
91
|
|
|
91
92
|
## 헬퍼가 하는 일
|
|
92
93
|
|
|
94
|
+
모든 pack build는 기존 `pack_id`를 바꾸지 않고 렌더링된 byte의 SHA-256 `content_address`를 포함합니다. `build`와 `auto`의 선택적 `--delta-from-pack-id PACK_ID`는 private local receipt 하나만 bounded/fail-soft 방식으로 비교합니다. `rolling_delta`는 진단 전용이고 selection이나 pack 본문을 바꾸지 않으며 provider token/cost savings claim이 아닙니다. 진단은 `--json` 출력 또는 저장된 artifact receipt에서만 보고됩니다. `--no-artifact`를 쓰면 진단 보고에 `--json`이 필요하며, 기존 text stdout은 정확한 pack 본문을 그대로 유지합니다.
|
|
95
|
+
|
|
96
|
+
선택적 `build`/`auto --sketch-duplicate-veto`는 sanitized slice에 rank-stable pre-budget gate를 적용하며 `suggest`는 그대로 둡니다. exact digest 후보는 byte로 확인합니다. 근사 gate는 고정 framing의 Unicode-casefold 순서 보존 5-token shingle, bottom 64 unique digest, 양쪽 최소 12, inclusive 0.90의 sketch-set Jaccard입니다. 짧은 sketch는 exact-only입니다. eligible pair 100,000개 검증 뒤 실제 skipped pair에서 fail open하고 이후 digest-only로 동작합니다. winner가 최종 budget에서 렌더링되지 않을 수 있으므로 누락 source 자체의 exact retrieval을 편집/근거 사용 전에 확인하십시오. `sketch_duplicate_source`, standalone build/`auto.build`의 `sketch_duplicate_veto.comparison_cap_reached`, flagged text의 `sketch_comparison_cap_reached=true|false`만 receipt 실패와 무관하게 관측됩니다. fingerprint, match identity, overlap, score, provider token/cost savings claim은 내보내지 않으며 flag-off 동작은 호환됩니다.
|
|
97
|
+
|
|
93
98
|
- **설정 마법사**는 `.claude/settings.json`을 덮어쓰지 않고 병합한 뒤, 읽기 전용 `context-guard-diet scan` 요약을 보여줍니다. 자동화에서 적용 후 검사 요약이 필요 없으면 `--no-diet-scan`을 사용하세요. `PATH` helper fallback은 기본적으로 꺼져 있으며, `--allow-path-helper-fallback`과 identity 검증을 통과해야만 사용됩니다.
|
|
94
99
|
- **컨텍스트 관리 스캐너**는 누락된 `permissions.deny` 가드레일, Bash 출력 축약 훅, 상태표시줄 설정, 넓은 읽기 허용, 비용이 큰 기본 모델/추론 강도, 많은 MCP 서버, 크거나 민감해 보이는 에이전트 규칙 파일, 부피가 크거나 민감해 보이는 로컬 경로에 대한 자문형 context-exclusion 추천을 확인합니다.
|
|
95
100
|
- **대용량 읽기 가드와 심볼 리더**는 파일 전체 읽기 전에 검색, 심볼 구간, 작은 줄 범위 읽기 순서로 에이전트를 안내합니다. Python, JavaScript/TypeScript, Go, Rust 소스 구간 읽기를 지원합니다.
|
|
@@ -105,6 +110,12 @@ context-guard-statusline-merged
|
|
|
105
110
|
- **반복 실패 알림**은 Bash 실패가 반복될 때 같은 경로를 계속 재시도하지 않고 전략을 바꾸도록 안내합니다.
|
|
106
111
|
- **벤치마크 헬퍼**는 기준/변형 실행을 대응해 실제 토큰·비용 필드, 별도의 바이트 감소 간접 증거, 진단용 `wall_time_seconds`, `provider_cached_tokens`, provider-cache 사용 가능성 텔레메트리, report-level measurement-baseline contract, 파일 기반 `variant_prompt_files`, 선택적 run별 `self_hosted_metrics` JSONL ledger sidecar를 기록합니다. 이 sidecar는 hosted API 절감 주장에 합치지 않습니다.
|
|
107
112
|
|
|
113
|
+
### Claude Read의 정확한 적용 범위
|
|
114
|
+
|
|
115
|
+
설치되는 가드는 Claude Code `PreToolUse`의 `Read` matcher 훅입니다. 이 가드를 선택하면 setup은 기존 deny 값 중 정확히 `Read(./.env)`와 `Read(./.env.*)`만 제거하고, 비슷한 항목과 상대적 순서는 유지합니다. 훅은 제한된 대용량 파일 범위를 검사하고, root 또는 중첩 경로의 basename이 `.env`로 시작하면 차단합니다. 단, 정확히 `.env.example`, `.env.sample`, `.env.template`인 템플릿 이름은 허용하며 symlink 여부가 모호하면 차단합니다. `Glob`은 이름을 나열할 수 있습니다. `Grep`과 `Bash`는 파일 내용을 읽을 수 있고 이 훅의 범위 밖입니다. 이는 범용 `.env` 보호나 Bash 보호가 아닙니다.
|
|
116
|
+
|
|
117
|
+
훅은 symlink를 따라가지 않고 파일을 열어 같은 descriptor의 identity, size, modification time을 다시 검증합니다. 실제 Claude `Read`는 훅 반환 뒤 별도로 파일을 열기 때문에, 그 post-hook 구간의 파일 교체 가능성은 문서화된 TOCTOU 한계로 남습니다.
|
|
118
|
+
|
|
108
119
|
비용 가드의 로컬 HMAC 키는 기본적으로 `.context-guard/cost-ledger/hmac.key`에 자동 생성됩니다. 관리자가 직접 주입하는 경우 파일에는 필수 padding을 포함한 canonical URL-safe base64 32바이트 키만 정확히 들어 있어야 하며, trailing newline이나 공백은 허용하지 않습니다. 리포트는 키와 원문 프롬프트를 출력하지 않고, 로컬 ledger는 Anthropic/provider prompt cache를 대체하지 않습니다.
|
|
109
120
|
|
|
110
121
|
## brief 모드 (안내용)
|
|
@@ -113,6 +124,18 @@ brief 모드는 코딩 에이전트가 군더더기를 줄이도록 요청하되
|
|
|
113
124
|
|
|
114
125
|
세 가지 고정 레벨(`lite`, `standard`, `ultra`)이 [`brief/`](brief/)에 있습니다. 각 레벨은 에이전트 규칙·지시 파일(`AGENTS.md`, `CLAUDE.md`, Cursor 규칙 파일, Copilot 지시 등)에 들어가는 마커 구분 블록입니다. `context-guard setup --agent codex --scope project --brief-mode standard --plan`으로 미리 보고, `--yes`로 적용하며, 제거는 `--brief-mode off`를 사용하세요. 자세한 내용은 [`brief/README.md`](brief/README.md)를 참고하세요.
|
|
115
126
|
|
|
127
|
+
## Claude 조용한 진행 설명 (안내용)
|
|
128
|
+
|
|
129
|
+
조용한 진행 설명은 기본적으로 꺼져 있는 별도의 Claude 전용 규칙입니다. 선택적 사전 설명, 도구별 진행 중계, 군더기, 반복 중간 요약은 줄이되 승인·결정, 차단 요인, 실패, 파괴적 작업·보안 경고, 필수 진행 보고, 최종 결과, 변경 파일, 검증 결과는 유지합니다.
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
context-guard setup --rules-only --agent claude --scope project --narration-mode quiet --plan
|
|
133
|
+
context-guard setup --rules-only --agent claude --scope project --narration-mode quiet --yes
|
|
134
|
+
context-guard setup --rules-only --agent claude --scope project --narration-mode default --yes
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
이 격리된 작업은 프로젝트 `CLAUDE.md`의 ContextGuard narration 구간만 관리하며 settings, hook 또는 다른 에이전트 파일을 읽거나 바꾸지 않고 일반 setup 작업과 함께 사용할 수 없습니다. 최종 답변의 간결성·추론 깊이와 별개인 최선 노력 규칙이며, Gate C는 모델 준수나 절감 효과를 주장하지 않습니다.
|
|
138
|
+
|
|
116
139
|
## 절감 수치를 과장하지 않습니다
|
|
117
140
|
|
|
118
141
|
이 헬퍼들은 흔히 컨텍스트를 불필요하게 키우는 원인을 줄이지만, 고정된 절감률을 보장하지 않습니다. 실제 전후 비교 증거가 필요하면 `context-guard-bench --ledger-jsonl ... --report-json ... --dashboard-md ...`로 본인 작업에서 측정하세요. `--evidence-jsonl ...`는 deterministic local replay용이며 provider-export provenance가 완전하지 않으면 public claim 불가로 표시됩니다. 토큰 절감 주장은 대응 태스크 양쪽 모두에 `primary_tokens_measured`가 있을 때만 계산하며, report의 `matched_pair_evidence`가 성공한 baseline/variant task bucket을 transform, quality gate, 측정 가능 여부, claim boundary와 연결합니다. report의 `default_matrix`는 같은 evidence에서 trimming, artifact escrow, tool pruning, cache advice, adaptive-k, optional compression을 `default-on`/`advisory`/`experimental`/`reject/rework`로 분류하지만 report 전용이며 runtime default나 hosted savings claim을 바꾸지 않습니다. report의 `public_claim_readiness`는 release/public claim의 최종 gate로, matched successful task, provider-measured primary token/cost, quality non-inferiority, shifted-cost accounting, 명시적 confidence/failure note, complete provider-export provenance가 모두 통과해야 `claim_allowed=true`가 되며 그 외 hosted savings claim은 금지됩니다. wall-time과 provider-cache 필드는 진단용 텔레메트리이지 단독 절감 증거가 아닙니다. 감사의 `cache_friendliness`, [`cache_diagnostics`](https://github.com/ictechgy/context-guard/blob/main/docs/cache-diagnostics-schema.md), `cache_layout_advice`는 관측/추론/가설/불가 경계를 둔 휴리스틱 배치·cache-read 신호와 순위화된 확인/실험이며 청구 기준이나 provider-cache 증명이 아닙니다. 벤치마크 CSV 스키마는 엄격하므로 헬퍼 업그레이드 후에는 새 CSV를 시작하거나 헤더를 마이그레이션하세요. 작업 유형별 합성 예시는 [`docs/benchmark-workflow-examples.md`](https://github.com/ictechgy/context-guard/blob/main/docs/benchmark-workflow-examples.md)에 있고, fixture-only 실험 시작 예시는 [`docs/experimental-benchmark-fixtures.md`](https://github.com/ictechgy/context-guard/blob/main/docs/experimental-benchmark-fixtures.md)에 있습니다.
|
|
@@ -121,12 +144,22 @@ ContextGuard는 모델 토큰을 줄이기 위해 작업을 외부 AI 서비스
|
|
|
121
144
|
|
|
122
145
|
미래 learned, self-hosted 최적화 아이디어는 [`research/experimental-token-reduction-radar.md`](https://github.com/ictechgy/context-guard/blob/main/research/experimental-token-reduction-radar.md)에 gated experiment로 기록하며, fixture-only 시작 예시는 [`docs/experimental-benchmark-fixtures.md`](https://github.com/ictechgy/context-guard/blob/main/docs/experimental-benchmark-fixtures.md)에 둡니다. learned compression은 `context-guard experiments plan learned-compression` dry-run checker와 명시적 `context-guard experiments emit learned-compression` caller-supplied candidate emitter만 shipped 상태이고, self-hosted-metrics-ledger는 dry-run preview와 명시적 `context-guard experiments record self-hosted-metrics-ledger` local JSONL record를 제공하며, dry-run preview는 ledger 파일을 쓰지 않습니다. visual crop/OCR은 caller-supplied evidence-pack emit, image-context-pack은 pxpipe-inspired image/context packing 평가를 위한 plan-only dry-run gate, semantic-checkpoint는 review용 task-state checkpoint 계획을 위한 plan-only/eval-only gate, context-diff는 verified-receipt caller-supplied replacement emit만 제공합니다. image-context-pack은 exact text artifact fallback, protected-zone denial, provider-boundary acknowledgement for provider-measured matched tasks, missed-context guardrail, 그리고 visual-crop-ocr이 기존 caller-supplied visual evidence-pack surface라는 plan output 확인이 필요하며, image rendering, OCR 실행, image parsing, model/provider call, proxy traffic, binary artifact 저장, replacement evidence 출력, hosted token/cost savings claim을 하지 않습니다. semantic-checkpoint는 CLI flag가 optional이지만 JSON readiness에서 exact context fallback/re-expand, provider-boundary ack, protected-zone policy `deny`, missed-context note, provenance review note가 없으면 blocked이며, `--missing-provenance-note`는 `none known after review` 같은 검토 확인 문구일 수 있습니다. 허용되는 re-expand command는 `context-guard-artifact get <id> --full` 또는 `context-guard artifact get <id> --full` 형태이고, emit/record/serve runtime, 새 `context-guard-semantic-checkpoint` binary, file write, transcript/prompt edit, model/provider/network call, replacement context, hosted token/cost savings claim은 없습니다. local proxy는 `context-guard experiments plan local-proxy` localhost-only dry-run advisory plan, design-only `context-guard experiments plan local-proxy-external-forwarding` gate, 명시적 `context-guard experiments record local-proxy-runtime-gate --ledger-jsonl ...` gate row record, private ready-file nonce가 필요한 one-shot `context-guard experiments serve local-proxy` loopback forwarding MVP와 successful forwarded request용 optional shifted-cost diagnostic JSONL row만 shipped 상태입니다. record는 no listener/no traffic forwarding/no DNS lookup/no external service/no API-key persistence boundary를 유지하고, serve는 private ready-file nonce, literal loopback IP, `--once`, credential-free request만 허용하고 CONNECT/TLS proxying도 지원하지 않습니다. `--response-sandbox`는 safe UTF-8 response text만 local artifact receipt로 저장하고 raw body 대신 redacted rehydration command template가 담긴 compact envelope를 돌려주며 hosted token/cost savings claim은 아닙니다. `--diagnostic-ledger-jsonl`은 successful forwarded request 뒤에만 진단 row를 쓰며 raw header/body나 hosted-savings evidence를 저장하지 않습니다. `plan local-proxy-external-forwarding`은 threat model, HTTPS allowlist, credential redaction, provider-evidence boundary를 점검하는 dry-run design gate이고 listener, DNS lookup, external service call, traffic forwarding, credential persistence, external proxy forwarding runtime, hosted savings claim을 제공하지 않습니다. learned/synthetic compressor 실행·embedding·reranker·model call·생성형 replacement, generated OCR/crop, visual-token pruning, plan-only image-context-pack dry-run gate를 넘어선 image-context-pack rendering/runtime, plan-only semantic-checkpoint gate를 넘어선 emit/record/serve runtime이나 replacement context/file-writing checkpoint store/transcript-prompt edit/provider-backed checkpointing, self-hosted KV/latent runtime 최적화, one-shot literal-loopback local proxy MVP를 넘어선 external/daemon/credential-bearing proxy forwarding runtime은 shipped가 아닙니다. 이 radar와 fixture는 provider가 측정한 matched-task 근거 없이 hosted API 절감을 주장하지 않습니다. Radar의 later-roadmap gate는 neural/semantic compression, trust-tiered injection-aware compression, generated visual-token reduction, broader local proxy forwarding constraint도 별도 미래 PR이 gate를 통과하기 전까지 experimental/non-shipped로 묶습니다.
|
|
123
146
|
|
|
147
|
+
`plan proof-carrying-context`는 bounded repeatable inline JSON의 proof-envelope metadata 구문과 정의된 일관성만 확인하는 기본 비활성 plan-only readiness gate입니다. Caller timestamp를 보존하지만 현재 시간이나 freshness는 검사하지 않고 protected-zone policy는 선언 전용입니다. 이 plan command에는 range bounds, receipt storage, source content, SHA-256, timestamp freshness, rehydration이 unchecked warning으로 남으며 source/artifact/config/stdin read, file write, model/provider/network/subprocess call, context 생성·대체, `emit`/`record`/`serve` runtime, 새 binary, hosted savings claim은 없습니다. `candidate_replacement`는 항상 `null`입니다.
|
|
148
|
+
|
|
149
|
+
`verify proof-carrying-context`는 별도의 read-only local verifier입니다. 문서 fixture는 정확한 UTF-8 문자열 `ContextGuard proof fixture\n`(27 bytes, 1 line)이고 SHA-256은 `12637068ee51f2ddfe27f1c00836a51cb54ba6a5cfca7f2301a4a45fbade2d14`입니다. Explicit artifact directory 하나만 사용하고 fallback search를 수행하지 않고 symlink를 follow하지 않으며 effective-user-owned directory `0700`과 두 receipt leaf 모두 mode `0600`을 요구합니다. Bounded whole-file read로 receipt/proof SHA, byte/line count, range bounds만 확인하고 range content는 retrieve/echo하지 않습니다. Exit `0`은 local binding pass, exit `2`는 verification failure이며 timestamp freshness/protected-zone semantics는 unchecked입니다. Rehydrate command는 syntax/receipt binding만 확인하고 실행하지 않으며 `candidate_replacement: null`을 유지하고 replacement/omission/hosted-savings authority를 부여하지 않습니다.
|
|
150
|
+
|
|
124
151
|
```bash
|
|
125
152
|
context-guard experiments plan semantic-checkpoint --json --goal "preserve current task state for review" --constraint "do not rewrite protected evidence" --decision "ship plan-only semantic-checkpoint gate first" --open-task "verify exact fallback before any checkpoint is used" --evidence-handle "roadmap=contextguard-artifact:0123456789abcdef" --missing-provenance-note "none known after review" --unresolved-question "which provenance handle fields become mandatory later" --exact-context-fallback-receipt 0123456789abcdef --reexpand-command "context-guard-artifact get 0123456789abcdef --full" --provider-boundary-ack --protected-zone-policy deny --missed-context-note "raw transcript remains retrievable before checkpoint metadata is used"
|
|
153
|
+
context-guard experiments plan proof-carrying-context --json --proof-unit-json '{"source_label":"context-filesystem-roadmap","receipt_id":"0123456789abcdef","content_sha256":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","safe_range":{"kind":"lines","start":82,"end":85},"captured_at":"2026-07-10T04:11:12Z","transform_policy":"safe_range_extract","rehydrate_command":"context-guard-artifact get 0123456789abcdef --full"}' --provider-boundary-ack --protected-zone-policy deny
|
|
154
|
+
context-guard experiments verify proof-carrying-context --artifact-dir ./artifacts --proof-unit-json '{"source_label":"context-filesystem-roadmap","receipt_id":"0123456789abcdef","content_sha256":"12637068ee51f2ddfe27f1c00836a51cb54ba6a5cfca7f2301a4a45fbade2d14","safe_range":{"kind":"lines","start":1,"end":1},"captured_at":"2026-07-10T04:11:12Z","transform_policy":"safe_range_extract","rehydrate_command":"context-guard-artifact get 0123456789abcdef --full"}' --json
|
|
126
155
|
```
|
|
127
156
|
|
|
128
157
|
교차 에이전트 규칙 스니펫은 안내용입니다. 대상 에이전트가 반드시 따른다고 보장할 수 없으므로, 절감 주장이 필요하면 실제 전후 동작을 직접 측정하세요.
|
|
129
158
|
|
|
159
|
+
## 로컬 MCP 어댑터
|
|
160
|
+
|
|
161
|
+
`context-guard mcp`와 `context-guard-mcp`는 의존성 없는 로컬 stdio MCP 자식 프로세스를 실행합니다. 프로세스는 root와 namespace 하나로 격리되고 sanitization된 compression, 정확한 sanitization artifact fallback, 로컬 통계만 제공합니다. HTTP, 네트워크, provider, model, proxy 통합이나 client 설정 변경은 없습니다. artifact는 namespace 사이에서 접근할 수 없고 hosted token/cost 절감도 주장하지 않습니다.
|
|
162
|
+
|
|
130
163
|
## 로컬 배포 테스트
|
|
131
164
|
|
|
132
165
|
마켓플레이스 저장소 루트에서 실행합니다.
|
|
@@ -148,6 +181,16 @@ claude --plugin-dir ./plugins/context-guard
|
|
|
148
181
|
/plugin install context-guard@context-guard
|
|
149
182
|
```
|
|
150
183
|
|
|
184
|
+
### 실험적 semantic-GC plan gate
|
|
185
|
+
|
|
186
|
+
`semantic-gc`는 기본 비활성화된 deny 전용 계획 검토 gate입니다. 기본 비활성화는 registry intent를 뜻하며, 명시적 plan CLI는 계속 실행할 수 있지만 omission이나 runtime action을 활성화하지 않습니다. 전체 envelope나 graph topology가 모호하면 graph evaluation을 억제합니다. 도달할 수 없는 node는 semantic irrelevance의 증명이 아니라 검토 후보일 뿐이며 omission과 runtime action은 승인되지 않습니다. missed-context note는 신뢰되지 않은 입력입니다. 이 planner는 context/artifact 내용을 읽지 않고 provenance, fallback, provider, hosted 절감을 검증하지 않습니다. Exit 0은 `ready_for_plan_review`만 뜻하며 delete/omit 권한이 아닙니다.
|
|
187
|
+
|
|
188
|
+
context-guard experiments plan semantic-gc --json --context-unit-json '{"schema":"contextguard.semantic-gc-unit.v1","unit_id":"root","references":[],"is_root":true,"protected_zone":false}' --context-unit-json '{"schema":"contextguard.semantic-gc-unit.v1","unit_id":"orphan","references":[],"is_root":false,"protected_zone":false,"content_sha256":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","provenance":{"source_label":"canonical-example","receipt_id":"0123456789abcdef"},"missed_context_note":"A reviewer could lose the orphaned rationale.","exact_fallback_command":"context-guard-artifact get 0123456789abcdef --full"}' --provider-boundary-ack --human-review-ack --protected-zone-policy deny
|
|
189
|
+
|
|
190
|
+
`static-relevance`는 호출자가 제공한 제한된 static evidence를 컴파일하는 기본 비활성화 기능입니다. 누락된 signal은 모든 slice와 review ordering을 억제하며, 빈 edge list도 검증된 관측이 아니라 선언입니다. protected path match와 명시적 보호 reason은 사람 검토에서 먼저 보게 하는 hard retention veto일 뿐입니다. 이 명령은 계획 검토 전용이며 repo를 읽지 않고, git을 호출하지 않으며, parser·provider·network·subprocess도 호출하지 않습니다. 결정적 review order에는 omit 권한이 없고 삭제·deprioritization·대체·runtime action도 승인하지 않습니다.
|
|
191
|
+
|
|
192
|
+
context-guard experiments plan static-relevance --json --relevance-unit-json '{"schema":"contextguard.static-relevance-unit.v1","unit_id":"src/cli.py::main","path":"src/cli.py","task_anchor":true,"protection_reasons":[],"symbol":{"name":"main","kind":"function","start_line":1,"end_line":40},"symbol_references":[],"dataflow_predecessors":[],"dataflow_successors":[],"git":{"blame_age_days":2,"blame_contributor_count":1,"path_change_count_90d":3}}' --protected-path-policy deny --provider-boundary-ack
|
|
193
|
+
|
|
151
194
|
## 라이선스
|
|
152
195
|
|
|
153
196
|
Copyright 2026 jinhongan. Apache License 2.0으로 배포됩니다. [LICENSE](LICENSE)와 [NOTICE](NOTICE)를 참고하세요.
|
|
@@ -85,6 +85,7 @@ context-guard-filter validate --config .context-guard/filter-dsl.json
|
|
|
85
85
|
context-guard-filter run --config .context-guard/filter-dsl.json -- git status --short
|
|
86
86
|
context-guard-pack auto --root . --query "review failing tests" --diff HEAD --manifest-out suggested-pack.json --pack-out context-pack.md --budget-bytes 12000 --json --explain --adaptive-k --adaptive-k-policy recall --symbol-memory
|
|
87
87
|
context-guard-pack build --root . --manifest suggested-pack.json --budget-bytes 12000 --json
|
|
88
|
+
context-guard-pack build --root . --manifest suggested-pack.json --budget-bytes 12000 --json --no-artifact --delta-from-pack-id 0123456789abcdef0123
|
|
88
89
|
context-guard-pack slice --root . --path README.md --lines 1:40 --json
|
|
89
90
|
context-guard-cache-score --input prompt.json --provider openai --json
|
|
90
91
|
context-guard cache-score --input prompt.txt --provider anthropic --json
|
|
@@ -97,6 +98,10 @@ context-guard-statusline-merged
|
|
|
97
98
|
|
|
98
99
|
## What the helpers do
|
|
99
100
|
|
|
101
|
+
Every pack build includes a rendered-byte SHA-256 `content_address` without changing the legacy `pack_id`. `build` and `auto` accept opt-in `--delta-from-pack-id PACK_ID` for bounded, fail-soft diagnostics against exactly one private local receipt; `rolling_delta` is diagnostic-only, changes no selection or pack content, and is not a provider token/cost savings claim. Diagnostics are reported only in `--json` output or a stored artifact receipt; with `--no-artifact`, `--json` is required to report them, while legacy text stdout remains the exact pack body.
|
|
102
|
+
|
|
103
|
+
Opt-in `build`/`auto --sketch-duplicate-veto` applies a rank-stable pre-budget gate to sanitized slices; `suggest` stays unchanged. Exact digest candidates are byte-confirmed. The approximate gate is sketch-set Jaccard over frozen Unicode-casefolded ordered five-token shingles: bottom 64 unique digests, minimum 12 on both sides, inclusive 0.90. Short sketches are exact-only. After 100,000 verified eligible pairs, the first skipped pair fails open and later work is digest-only. A winner may not render under the final budget, so use the omitted source's own exact retrieval before editing or relying on it. Only `sketch_duplicate_source`, standalone build/`auto.build` `sketch_duplicate_veto.comparison_cap_reached`, and flagged text `sketch_comparison_cap_reached=true|false` are observable, even when receipt storage fails. No fingerprint, match identity, overlap, score, provider token/cost savings claim is emitted; flag-off behavior is compatible.
|
|
104
|
+
|
|
100
105
|
- **Setup wizard** merges `.claude/settings.json` instead of replacing it, then prints a read-only `context-guard-diet scan` summary. Use `context-guard doctor` or `context-guard setup --verify` for a read-only health check before applying setup; use `--no-diet-scan` when automation needs setup output without the post-apply scan. `PATH` helper fallback is default-off and requires `--allow-path-helper-fallback` plus identity validation.
|
|
101
106
|
- **Context management scanner** checks missing `permissions.deny` guardrails, Bash trim hook/statusline setup, broad read allows, high default model/effort, many MCP servers, large or secret-like agent rule files, and advisory context-exclusion recommendations for bulky/sensitive local paths. Its `--top` cap applies to both context-like files and context-exclusion recommendations.
|
|
102
107
|
- **Structural-waste doctor** is an opt-in read-only `context-guard-diet structural-waste` report for duplicate rule units, stale Python import candidates, unused skill candidates, excessive MCP/tool schema catalogs, and repeated file reads or duplicate tool calls in local JSON/JSONL logs. It does not mutate config, call the network, or print raw prompt/tool-input text; low-confidence import/skill findings are review prompts, not delete instructions.
|
|
@@ -114,6 +119,12 @@ context-guard-statusline-merged
|
|
|
114
119
|
- **Repeated-failure nudge** warns after repeated Bash failures so the agent switches strategy instead of retrying the same context-heavy path.
|
|
115
120
|
- **Benchmark helper** records matched baseline/variant runs with real token and cost fields, separate byte-reduction proxy evidence, diagnostic `wall_time_seconds`, `provider_cached_tokens`, provider-cache availability telemetry, a report-level measurement-baseline contract, file-backed `variant_prompt_files`, and optional per-run `self_hosted_metrics` JSONL ledger sidecars that stay out of hosted API savings claims.
|
|
116
121
|
|
|
122
|
+
### Exact Claude Read surface
|
|
123
|
+
|
|
124
|
+
The installed guard is a Claude Code `PreToolUse` hook with matcher `Read`. When selected, setup removes only the exact legacy deny values `Read(./.env)` and `Read(./.env.*)` while preserving similar entries and their relative order. The hook checks bounded large-file ranges and denies root or nested paths whose basename begins `.env`, except the exact template names `.env.example`, `.env.sample`, and `.env.template`; ambiguous symlink paths fail closed. `Glob` can still list names. `Grep` and `Bash` can read file contents and are outside this hook. This is not universal `.env` or Bash protection.
|
|
125
|
+
|
|
126
|
+
The hook opens without following symlinks and revalidates identity, size, and modification time on that descriptor. Claude performs the actual `Read` with a separate open after the hook returns, so replacement during that post-hook window remains a documented TOCTOU limitation.
|
|
127
|
+
|
|
117
128
|
Cost guard creates its local HMAC key automatically at `.context-guard/cost-ledger/hmac.key`. If you provision that file yourself, it must contain exactly one canonical URL-safe base64 32-byte key with required padding and no trailing newline or whitespace. Reports never emit the key or raw prompt text, and the local ledger does not replace Anthropic/provider prompt caching.
|
|
118
129
|
|
|
119
130
|
## Brief mode (advisory)
|
|
@@ -122,6 +133,18 @@ Brief mode ships agent-neutral, advisory rule snippets that ask a coding agent t
|
|
|
122
133
|
|
|
123
134
|
Three deterministic levels — `lite`, `standard`, `ultra` — live under [`brief/`](brief/). Each is a single marker-delimited block for an agent's rule/instruction file (such as `AGENTS.md`, `CLAUDE.md`, a Cursor rules file, or Copilot instructions). Use `context-guard setup --agent codex --scope project --brief-mode standard --plan`, apply with `--yes`, and remove with `--brief-mode off`. See [`brief/README.md`](brief/README.md).
|
|
124
135
|
|
|
136
|
+
## Quiet narration for Claude (advisory)
|
|
137
|
+
|
|
138
|
+
Quiet narration is a separate, default-off Claude-only rule that suppresses discretionary preambles, per-tool narration, filler, and repeated interim summaries while preserving approvals and decisions, blockers, failures, destructive or security warnings, required progress, the final result, changed files, and verification.
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
context-guard setup --rules-only --agent claude --scope project --narration-mode quiet --plan
|
|
142
|
+
context-guard setup --rules-only --agent claude --scope project --narration-mode quiet --yes
|
|
143
|
+
context-guard setup --rules-only --agent claude --scope project --narration-mode default --yes
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The isolated operation manages only ContextGuard's narration span in project `CLAUDE.md`; it does not read or change settings, hooks, or other agents' files and cannot be combined with normal setup actions. The rule is best-effort, independent of final-answer brevity or reasoning depth, and Gate C makes no model-compliance or savings claim.
|
|
147
|
+
|
|
125
148
|
## Conservative claims
|
|
126
149
|
|
|
127
150
|
These helpers reduce common sources of context bloat, but they do not guarantee a fixed percentage savings. Use `context-guard-bench --ledger-jsonl ... --report-json ... --dashboard-md ...` when you need measured before/after evidence for your own tasks; add `--evidence-jsonl ...` only for deterministic local replay that remains non-claim-eligible unless provider-export provenance is complete; token-savings claims require `primary_tokens_measured` on both matched sides, and the report's `matched_pair_evidence` links each successful baseline/variant task bucket to the transform, quality gate, measurement availability, and claim boundary. The report's `default_matrix` classifies trimming, artifact escrow, tool pruning, cache advice, adaptive-k, and optional compression as `default-on`, `advisory`, `experimental`, or `reject/rework` from that evidence, but it is reporting-only and does not change runtime defaults or authorize hosted savings claims. The report's `public_claim_readiness` is the authoritative release/public-claim gate: matched successful tasks, provider-measured primary tokens/cost, quality non-inferiority, shifted-cost accounting, explicit confidence/failure notes, and complete provider-export provenance must all pass before `claim_allowed=true`; unsupported hosted savings claims are forbidden otherwise. Wall-time/provider-cache fields are diagnostic telemetry, not standalone savings proof. Audit `cache_friendliness`, [`cache_diagnostics`](https://github.com/ictechgy/context-guard/blob/main/docs/cache-diagnostics-schema.md), and `cache_layout_advice` findings are heuristic layout/cache-read signals and ranked checks/experiments with observed/inferred/hypothesis/unavailable boundaries, not billing authority or provider-cache proof. Benchmark CSV schemas are strict, so start a new CSV or migrate the header after helper upgrades. Workflow-specific synthetic examples live in [`docs/benchmark-workflow-examples.md`](https://github.com/ictechgy/context-guard/blob/main/docs/benchmark-workflow-examples.md), and fixture-only experimental task/variant starters live in [`docs/experimental-benchmark-fixtures.md`](https://github.com/ictechgy/context-guard/blob/main/docs/experimental-benchmark-fixtures.md).
|
|
@@ -143,6 +166,8 @@ context-guard experiments plan visual-crop-ocr --json --full-evidence-receipt <i
|
|
|
143
166
|
context-guard experiments emit visual-crop-ocr --json --full-evidence-receipt <id> --crop-label <label> --crop-bounds 0,0,100,100 --image-size 800,600 --ocr-text "visible text" --ocr-confidence 0.9 --ocr-error-note "glyph may be uncertain" --missed-context-note "outside crop omitted"
|
|
144
167
|
context-guard experiments plan image-context-pack --json --exact-text-fallback-receipt <id> --reexpand-command "context-guard-artifact get <id> --full" --provider-boundary-ack --protected-zone-policy deny --missed-context-note "omitted text remains retrievable before any future image pack is used" --image-size 800,600 --packed-image-size 400,300
|
|
145
168
|
context-guard experiments plan semantic-checkpoint --json --goal "preserve current task state for review" --constraint "do not rewrite protected evidence" --decision "ship plan-only semantic-checkpoint gate first" --open-task "verify exact fallback before any checkpoint is used" --evidence-handle "roadmap=contextguard-artifact:0123456789abcdef" --missing-provenance-note "none known after review" --unresolved-question "which provenance handle fields become mandatory later" --exact-context-fallback-receipt 0123456789abcdef --reexpand-command "context-guard-artifact get 0123456789abcdef --full" --provider-boundary-ack --protected-zone-policy deny --missed-context-note "raw transcript remains retrievable before checkpoint metadata is used"
|
|
169
|
+
context-guard experiments plan proof-carrying-context --json --proof-unit-json '{"source_label":"context-filesystem-roadmap","receipt_id":"0123456789abcdef","content_sha256":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","safe_range":{"kind":"lines","start":82,"end":85},"captured_at":"2026-07-10T04:11:12Z","transform_policy":"safe_range_extract","rehydrate_command":"context-guard-artifact get 0123456789abcdef --full"}' --provider-boundary-ack --protected-zone-policy deny
|
|
170
|
+
context-guard experiments verify proof-carrying-context --artifact-dir ./artifacts --proof-unit-json '{"source_label":"context-filesystem-roadmap","receipt_id":"0123456789abcdef","content_sha256":"12637068ee51f2ddfe27f1c00836a51cb54ba6a5cfca7f2301a4a45fbade2d14","safe_range":{"kind":"lines","start":1,"end":1},"captured_at":"2026-07-10T04:11:12Z","transform_policy":"safe_range_extract","rehydrate_command":"context-guard-artifact get 0123456789abcdef --full"}' --json
|
|
146
171
|
context-guard experiments plan learned-compression --json --sanitized --trusted-source --exact-fallback-receipt <id> --reexpand-command "context-guard-artifact get <id> --full" < sanitized-prose.txt
|
|
147
172
|
context-guard experiments emit learned-compression --json --sanitized --trusted-source --exact-fallback-receipt <id> --reexpand-command "context-guard-artifact get <id> --full" --replacement-file compact-prose.txt < sanitized-prose.txt
|
|
148
173
|
context-guard experiments plan self-hosted-metrics-ledger --json --latency-ms 123.5 --peak-memory-mb 2048 --quality-score 0.98
|
|
@@ -159,10 +184,18 @@ context-guard experiments disable output-receipt-trim --root .
|
|
|
159
184
|
|
|
160
185
|
`semantic-checkpoint` is a plan-only/eval-only gate for reviewable task-state checkpoint planning. Its flags are optional at the CLI so incomplete dry runs can return JSON, but readiness remains blocked in the JSON payload until the plan includes a goal, exact fallback receipt, local re-expand command, provider-boundary acknowledgement, protected-zone policy `deny`, missed-context note, and provenance review note. `--missing-provenance-note` can be a review acknowledgement such as `none known after review`; allowed local re-expand shapes are `context-guard-artifact get <id> --full` and `context-guard artifact get <id> --full`. It has no `emit`, `record`, or `serve` runtime, no new `context-guard-semantic-checkpoint` binary, writes no files, edits no transcript or prompt, calls no model/provider/network, emits no replacement context, and makes no hosted token/cost savings claim.
|
|
161
186
|
|
|
187
|
+
`plan proof-carrying-context` is the default-off plan-only proof-envelope metadata readiness gate. It accepts bounded repeatable inline JSON and validates syntax/defined consistency only; caller timestamps are preserved without current-time generation or freshness checks. Protected-zone policy is declared-only, while range bounds, receipt storage, source content, SHA-256, timestamp freshness, and rehydration stay unchecked and visible as warnings. This plan command reads no source/artifact/config/stdin content, writes no files, invokes no model/provider/network/subprocess, generates or replaces no context (`candidate_replacement` is always `null`), exposes no `emit`/`record`/`serve` runtime or new binary, and makes no hosted token/cost savings claim without provider-measured matched successful tasks.
|
|
188
|
+
|
|
189
|
+
`verify proof-carrying-context` is the separate read-only local verifier. Its documented fixture is the exact UTF-8 string `ContextGuard proof fixture\n` (27 bytes, one line), SHA-256 `12637068ee51f2ddfe27f1c00836a51cb54ba6a5cfca7f2301a4a45fbade2d14`. It uses one explicit artifact directory, performs no fallback search, follows no symlink, and requires effective-user ownership plus directory mode `0700` and both receipt leaves with mode `0600`. It reads the complete bounded file for receipt/proof SHA, byte/line, and range-bounds verification but never retrieves or echoes range content. Exit `0` means only local bindings passed and exit `2` means verification failed; timestamp freshness and protected-zone semantics stay unchecked, rehydrate commands are syntax/receipt checked but never executed, `candidate_replacement` stays `null`, and no replacement, omission, or hosted-savings authority is granted.
|
|
190
|
+
|
|
162
191
|
Use `--config <path>` only for an explicit project-local override. Registry entries include risk, gate requirements, explicit command/flag surfaces, and claim boundaries; hosted API token/cost savings still require provider-measured matched-task evidence. The registry can discover existing explicit-flag experiments such as `context-guard-trim-output --digest ... --artifact-receipt` and `context-guard-compress --protected-policy`, run dry-run advisory planners such as `context-guard experiments plan context-diff-compaction`, `context-guard experiments plan visual-crop-ocr`, `context-guard experiments plan learned-compression`, `context-guard experiments plan semantic-checkpoint`, `context-guard experiments plan self-hosted-metrics-ledger`, `context-guard experiments plan local-proxy`, and design-only `context-guard experiments plan local-proxy-external-forwarding`, and run explicit local runtimes such as `context-guard experiments emit context-diff-compaction ...`, `context-guard experiments emit visual-crop-ocr ...`, `context-guard experiments emit learned-compression ...`, `context-guard experiments record self-hosted-metrics-ledger ...`, `context-guard experiments record local-proxy-runtime-gate ...`, `context-guard experiments serve local-proxy ...`, and successful-forward `context-guard experiments serve local-proxy --diagnostic-ledger-jsonl ...` diagnostics. The context-diff emit runtime only emits caller-supplied compact replacements when reviewable hunks, exact local artifact re-expand metadata whose stored content matches the input diff, and a smaller replacement are present; it does not generate semantic compression or permit hosted savings claims. The visual lane ships a dry-run planner plus an explicit local evidence-pack emitter: both use only caller-supplied full-evidence receipts, crop metadata, OCR text, confidence/error notes, and missed-context notes; screenshot capture, image cropping, OCR execution, image parsing, external OCR/image services, output-file writes, and hosted savings claims are not shipped. The learned-compression lane ships a deny-by-default dry-run policy check plus an explicit local candidate emitter for caller-supplied compact prose with verified exact fallback content: learned/synthetic compressor execution, embeddings, rerankers, model calls, subprocesses, external services, generated replacement text, and hosted savings claims are not shipped. The semantic-checkpoint lane ships only the plan/eval gate above: no runtime emit/record/serve surface, file-writing checkpoint store, transcript/prompt edit, provider/model/network-backed checkpointing, replacement context, new binary, or hosted savings claim is shipped. The self-hosted metrics planner emits a dry-run ledger-compatible preview for explicit local/model-server latency, memory, quality, energy, throughput, and local-cost metrics; the dry-run preview does not write a ledger, while `context-guard experiments record self-hosted-metrics-ledger --ledger-jsonl ...` writes only local JSONL sidecars and still does not permit hosted API token/cost savings claims. The local-proxy planner emits localhost-only advisory metadata only, while `context-guard experiments record local-proxy-runtime-gate --ledger-jsonl ...` appends one local gate row only after localhost-only metadata and `--runtime-gate-ack`: it starts no listener, forwards no traffic, and performs no DNS lookup. `context-guard experiments serve local-proxy ...` is the separate forwarding MVP: it requires `--forwarding-gate-ack --once`, a private `--ready-file` nonce handoff, literal loopback bind/target IPs, no hostname DNS targets, nonzero ports, byte/time limits, and credential-free requests; it performs no external forwarding, no CONNECT/TLS proxying, no API-key persistence, and no hosted-savings claim. `--response-sandbox` can store safe UTF-8 response text as a sanitized local artifact receipt and return a compact envelope with redacted rehydration command templates; it does not claim hosted token/cost savings. `--diagnostic-ledger-jsonl` writes one shifted-cost diagnostic row only after a successful forwarded request, with no raw headers/bodies and no hosted-savings evidence. `plan local-proxy-external-forwarding` emits threat-model/allowlist/redaction/provider-evidence design metadata only and still starts no listener, performs no DNS lookup, calls no external service, forwards no traffic, persists no credentials, and does not ship an external proxy forwarding runtime. `experiments enable` records intent only; it does not run those helpers, remove the need for their explicit flags, or permit replacing content without exact receipt/re-expand evidence.
|
|
163
192
|
|
|
164
193
|
Cross-agent rule snippets are advisory: the target agent may ignore them, so measure actual before/after behavior when you need a savings claim.
|
|
165
194
|
|
|
195
|
+
## Local MCP adapter
|
|
196
|
+
|
|
197
|
+
`context-guard mcp` and `context-guard-mcp` launch a dependency-free local stdio MCP child process. A process is isolated to one root and namespace and exposes only sanitized compression, sanitized exact artifact fallback, and local statistics. It has no HTTP, network, provider, model, or proxy integration and never mutates client configuration. Artifacts are inaccessible across namespaces; no hosted token/cost savings are claimed.
|
|
198
|
+
|
|
166
199
|
## Local test before publishing
|
|
167
200
|
|
|
168
201
|
From the marketplace repository root:
|
|
@@ -184,6 +217,16 @@ Marketplace installation test:
|
|
|
184
217
|
/plugin install context-guard@context-guard
|
|
185
218
|
```
|
|
186
219
|
|
|
220
|
+
### Experimental semantic-GC plan gate
|
|
221
|
+
|
|
222
|
+
`semantic-gc` is a default-off, deny-only, plan-review gate over a caller-declared graph. Default-off describes registry intent; the explicit plan CLI remains invocable and never enables omission or runtime action. Graph evaluation is suppressed when the complete envelope or topology is ambiguous. Unreachable nodes are review candidates, not proof of semantic irrelevance: omission and runtime action remain unauthorized. Candidate missed-context notes are untrusted. The planner does not read context/artifact content or verify provenance, fallback, providers, or hosted savings. Exit 0 means only `ready_for_plan_review`; it is never delete/omit authority.
|
|
223
|
+
|
|
224
|
+
context-guard experiments plan semantic-gc --json --context-unit-json '{"schema":"contextguard.semantic-gc-unit.v1","unit_id":"root","references":[],"is_root":true,"protected_zone":false}' --context-unit-json '{"schema":"contextguard.semantic-gc-unit.v1","unit_id":"orphan","references":[],"is_root":false,"protected_zone":false,"content_sha256":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","provenance":{"source_label":"canonical-example","receipt_id":"0123456789abcdef"},"missed_context_note":"A reviewer could lose the orphaned rationale.","exact_fallback_command":"context-guard-artifact get 0123456789abcdef --full"}' --provider-boundary-ack --human-review-ack --protected-zone-policy deny
|
|
225
|
+
|
|
226
|
+
`static-relevance` is a default-off compiler for bounded caller-supplied static evidence. Missing signals suppress all slices and review ordering; accepted empty edge lists are declarations, not verified observations. Built-in protected-path matches and explicit protected reasons are hard retention vetoes that move evidence first for human review only. This plan-review-only command does not scan or read any repository, does not invoke git, and does not invoke a parser, provider, network, or subprocess. Its deterministic review order does not authorize omission, deletion, deprioritization, replacement, or runtime action.
|
|
227
|
+
|
|
228
|
+
context-guard experiments plan static-relevance --json --relevance-unit-json '{"schema":"contextguard.static-relevance-unit.v1","unit_id":"src/cli.py::main","path":"src/cli.py","task_anchor":true,"protection_reasons":[],"symbol":{"name":"main","kind":"function","start_line":1,"end_line":40},"symbol_references":[],"dataflow_predecessors":[],"dataflow_successors":[],"git":{"blame_age_days":2,"blame_contributor_count":1,"path_change_count_90d":3}}' --protected-path-policy deny --provider-boundary-ack
|
|
229
|
+
|
|
187
230
|
## License
|
|
188
231
|
|
|
189
232
|
Copyright 2026 jinhongan. Licensed under the Apache License 2.0. See [LICENSE](LICENSE) and [NOTICE](NOTICE).
|
|
@@ -144,8 +144,14 @@ def compact_items(lines: Iterable[str], *, limit: int, max_chars: int = MAX_LINE
|
|
|
144
144
|
|
|
145
145
|
|
|
146
146
|
class FallbackLineSanitizer:
|
|
147
|
-
def __init__(
|
|
147
|
+
def __init__(
|
|
148
|
+
self,
|
|
149
|
+
*,
|
|
150
|
+
show_paths: bool = False,
|
|
151
|
+
context: str = "unknown_text",
|
|
152
|
+
) -> None:
|
|
148
153
|
self.show_paths = show_paths
|
|
154
|
+
self.context = context
|
|
149
155
|
self.redactions = 0
|
|
150
156
|
|
|
151
157
|
def sanitize(self, raw_line: str) -> tuple[str, bool]:
|
|
@@ -161,7 +167,32 @@ class FallbackLineSanitizer:
|
|
|
161
167
|
return line, bool(count)
|
|
162
168
|
|
|
163
169
|
|
|
164
|
-
def
|
|
170
|
+
def instantiate_line_sanitizer(
|
|
171
|
+
factory: object,
|
|
172
|
+
*,
|
|
173
|
+
show_paths: bool,
|
|
174
|
+
context: str,
|
|
175
|
+
private_roots: tuple[str, ...] = (),
|
|
176
|
+
) -> object:
|
|
177
|
+
try:
|
|
178
|
+
return factory( # type: ignore[operator]
|
|
179
|
+
show_paths=show_paths,
|
|
180
|
+
context=context,
|
|
181
|
+
private_roots=private_roots,
|
|
182
|
+
)
|
|
183
|
+
except TypeError:
|
|
184
|
+
if context != "unknown_text" or private_roots:
|
|
185
|
+
raise RuntimeError(
|
|
186
|
+
"adjacent sanitizer does not support required explicit context"
|
|
187
|
+
)
|
|
188
|
+
return factory(show_paths=show_paths) # type: ignore[operator]
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def load_line_sanitizer(
|
|
192
|
+
show_paths: bool,
|
|
193
|
+
context: str = "unknown_text",
|
|
194
|
+
private_roots: tuple[str, ...] = (),
|
|
195
|
+
) -> object:
|
|
165
196
|
script_dir = Path(__file__).resolve().parent
|
|
166
197
|
for name in ("sanitize_output.py", "context-guard-sanitize-output", "claude-sanitize-output"):
|
|
167
198
|
candidate = script_dir / name
|
|
@@ -173,15 +204,35 @@ def load_line_sanitizer(show_paths: bool) -> object:
|
|
|
173
204
|
if spec is None:
|
|
174
205
|
raise RuntimeError("import spec unavailable")
|
|
175
206
|
module = importlib.util.module_from_spec(spec)
|
|
176
|
-
loader.
|
|
177
|
-
|
|
207
|
+
sys.modules[loader.name] = module
|
|
208
|
+
try:
|
|
209
|
+
loader.exec_module(module)
|
|
210
|
+
except Exception:
|
|
211
|
+
sys.modules.pop(loader.name, None)
|
|
212
|
+
raise
|
|
213
|
+
return instantiate_line_sanitizer(
|
|
214
|
+
module.LineSanitizer,
|
|
215
|
+
show_paths=show_paths,
|
|
216
|
+
context=context,
|
|
217
|
+
private_roots=private_roots,
|
|
218
|
+
)
|
|
178
219
|
except Exception as exc:
|
|
179
220
|
raise RuntimeError(f"could not load sanitizer {candidate}: {exc}") from exc
|
|
180
|
-
return FallbackLineSanitizer(show_paths=show_paths)
|
|
221
|
+
return FallbackLineSanitizer(show_paths=show_paths, context=context)
|
|
181
222
|
|
|
182
223
|
|
|
183
|
-
def sanitize_text(
|
|
184
|
-
|
|
224
|
+
def sanitize_text(
|
|
225
|
+
text: str,
|
|
226
|
+
*,
|
|
227
|
+
show_paths: bool = False,
|
|
228
|
+
context: str = "unknown_text",
|
|
229
|
+
private_roots: tuple[str, ...] = (),
|
|
230
|
+
) -> tuple[str, int]:
|
|
231
|
+
sanitizer = load_line_sanitizer(
|
|
232
|
+
show_paths,
|
|
233
|
+
context=context,
|
|
234
|
+
private_roots=private_roots,
|
|
235
|
+
)
|
|
185
236
|
redacted = 0
|
|
186
237
|
out: list[str] = []
|
|
187
238
|
for line in text.splitlines(True):
|
|
@@ -193,7 +244,11 @@ def sanitize_text(text: str, *, show_paths: bool = False) -> tuple[str, int]:
|
|
|
193
244
|
|
|
194
245
|
|
|
195
246
|
def sanitize_one_line(text: str, *, show_paths: bool = False) -> str:
|
|
196
|
-
sanitized, _ = sanitize_text(
|
|
247
|
+
sanitized, _ = sanitize_text(
|
|
248
|
+
text + "\n",
|
|
249
|
+
show_paths=show_paths,
|
|
250
|
+
context="unknown_text",
|
|
251
|
+
)
|
|
197
252
|
return cap_utf8_bytes(cap_line(" ".join(sanitized.strip().split())), MAX_COMMAND_PREVIEW_BYTES)
|
|
198
253
|
|
|
199
254
|
|
|
@@ -1103,7 +1158,12 @@ def store_command(args: argparse.Namespace) -> int:
|
|
|
1103
1158
|
directory = normalize_allowed_first_absolute_symlink(Path(args.dir).expanduser())
|
|
1104
1159
|
max_bytes = bounded_int(args.max_bytes, DEFAULT_MAX_BYTES, 1, MAX_MAX_BYTES)
|
|
1105
1160
|
raw_text, input_truncated, input_bytes = read_bounded_stdin(max_bytes)
|
|
1106
|
-
sanitized_text, redacted_lines = sanitize_text(
|
|
1161
|
+
sanitized_text, redacted_lines = sanitize_text(
|
|
1162
|
+
raw_text,
|
|
1163
|
+
show_paths=args.show_paths,
|
|
1164
|
+
context=args.sanitize_context,
|
|
1165
|
+
private_roots=tuple(args.private_root),
|
|
1166
|
+
)
|
|
1107
1167
|
content_bytes = len(sanitized_text.encode("utf-8", errors="replace"))
|
|
1108
1168
|
content_sha = hashlib.sha256(sanitized_text.encode("utf-8", errors="replace")).hexdigest()
|
|
1109
1169
|
command_preview = sanitize_one_line(args.command or "", show_paths=args.show_paths) if args.command else None
|
|
@@ -1125,6 +1185,10 @@ def store_command(args: argparse.Namespace) -> int:
|
|
|
1125
1185
|
"created_at": int(time.time()),
|
|
1126
1186
|
"command_preview": command_preview,
|
|
1127
1187
|
"content_type": content_type,
|
|
1188
|
+
"sanitization": {
|
|
1189
|
+
"context": args.sanitize_context,
|
|
1190
|
+
"redacted_lines": redacted_lines,
|
|
1191
|
+
},
|
|
1128
1192
|
"input": {
|
|
1129
1193
|
"bytes_read": input_bytes,
|
|
1130
1194
|
"truncated": input_truncated,
|
|
@@ -1682,6 +1746,23 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
1682
1746
|
action="store_true",
|
|
1683
1747
|
help="show raw absolute paths instead of path hashes; local debugging only because private paths may be exposed",
|
|
1684
1748
|
)
|
|
1749
|
+
store.add_argument(
|
|
1750
|
+
"--sanitize-context",
|
|
1751
|
+
choices=(
|
|
1752
|
+
"unknown_text",
|
|
1753
|
+
"command_search_diff",
|
|
1754
|
+
"filesystem_listing",
|
|
1755
|
+
"source_code",
|
|
1756
|
+
),
|
|
1757
|
+
default="unknown_text",
|
|
1758
|
+
help="persist the declared input origin used for sanitization",
|
|
1759
|
+
)
|
|
1760
|
+
store.add_argument(
|
|
1761
|
+
"--private-root",
|
|
1762
|
+
action="append",
|
|
1763
|
+
default=[],
|
|
1764
|
+
help="private root for filesystem_listing sanitization; may be repeated",
|
|
1765
|
+
)
|
|
1685
1766
|
store.add_argument("--json", action="store_true", help="emit receipt JSON")
|
|
1686
1767
|
store.set_defaults(func=store_command)
|
|
1687
1768
|
|