@ictechgy/context-guard 0.4.6 → 0.4.7
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 +7 -0
- package/README.ko.md +32 -4
- package/README.md +33 -3
- package/context-guard-kit/README.md +2 -0
- package/context-guard-kit/context_escrow.py +22 -6
- package/context-guard-kit/context_guard_cli.py +1 -0
- package/context-guard-kit/experimental_registry.py +2038 -0
- package/docs/benchmark-workflow-examples.md +1 -1
- package/docs/experimental-benchmark-fixtures.md +1 -1
- package/package.json +2 -1
- package/packaging/homebrew/context-guard.rb.template +1 -1
- package/plugins/context-guard/.claude-plugin/plugin.json +1 -1
- package/plugins/context-guard/README.ko.md +1 -1
- package/plugins/context-guard/README.md +19 -1
- package/plugins/context-guard/bin/context-guard +1 -0
- package/plugins/context-guard/bin/context-guard-artifact +22 -6
- package/plugins/context-guard/bin/context-guard-experiments +2038 -0
|
@@ -39,6 +39,6 @@ Avoid language like:
|
|
|
39
39
|
|
|
40
40
|
The `.example.json` fixtures intentionally use full `context-guard-bench-report-v1` shapes so tests can catch schema drift and overclaim wording.
|
|
41
41
|
|
|
42
|
-
The self-hosted metrics example is a JSONL run-evidence sidecar, not a full report shape. Its fields are additive ledger evidence only: `latency_ms`, `peak_memory_mb`, and normalized `quality_score` describe local/model-server behavior and leave hosted API report calculations unchanged.
|
|
42
|
+
The self-hosted metrics example is a JSONL run-evidence sidecar, not a full report shape. Its fields are additive ledger evidence only: `latency_ms`, `peak_memory_mb`, and normalized `quality_score` describe local/model-server behavior and leave hosted API report calculations unchanged. Use `context-guard experiments plan self-hosted-metrics-ledger --json ...` only as a dry-run ledger-preview checker for explicit metrics; it does not write the benchmark ledger.
|
|
43
43
|
|
|
44
44
|
For task/variant starter fixtures rather than full report-shape examples, see [`experimental-benchmark-fixtures.md`](experimental-benchmark-fixtures.md). Those files are fixture-only and synthetic dry-run-only starters until users replace the placeholder prompts and success checks; they are not shipped OCR, visual-token, learned-compression, or output-transform benchmark results, and real claims still require provider-measured matched successful tasks plus failure-rate, correction, and shifted-cost guardrails.
|
|
@@ -32,7 +32,7 @@ The visual/OCR fixtures describe sanitized textual visual evidence only and now
|
|
|
32
32
|
|
|
33
33
|
## Learned-compression fixture notes
|
|
34
34
|
|
|
35
|
-
The learned-compression fixtures describe already-sanitized context-pack or artifact-digest comparisons and now demonstrate `variant_prompt_files` for baseline context-pack evidence versus a fixture-only compressed digest candidate.
|
|
35
|
+
The learned-compression fixtures describe already-sanitized context-pack or artifact-digest comparisons and now demonstrate `variant_prompt_files` for baseline context-pack evidence versus a fixture-only compressed digest candidate. ContextGuard ships `context-guard experiments plan learned-compression` only as a deny-by-default dry-run checker for sanitized trusted prose plus exact fallback handles. It does not invoke or ship LLMLingua-style, gist-token, latent-context, embedding, reranking, model-call, or replacement-generation implementations. Future experiments must follow a sanitized evidence only rule, keep protected evidence exact or receipt-retrievable, forbid semantic rewrites of identifiers, numeric constants, hashes, paths, quoted strings, stack frames, JSON keys, code fences, and diff zones, and record bytes before/after, primary provider tokens, cost, success, corrections, compressor latency, and external cost.
|
|
36
36
|
|
|
37
37
|
## Reversible output-transform fixture notes
|
|
38
38
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ictechgy/context-guard",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.7",
|
|
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",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"context-guard": "plugins/context-guard/bin/context-guard",
|
|
17
17
|
"context-guard-setup": "plugins/context-guard/bin/context-guard-setup",
|
|
18
18
|
"context-guard-diet": "plugins/context-guard/bin/context-guard-diet",
|
|
19
|
+
"context-guard-experiments": "plugins/context-guard/bin/context-guard-experiments",
|
|
19
20
|
"context-guard-audit": "plugins/context-guard/bin/context-guard-audit",
|
|
20
21
|
"context-guard-trim-output": "plugins/context-guard/bin/context-guard-trim-output",
|
|
21
22
|
"context-guard-sanitize-output": "plugins/context-guard/bin/context-guard-sanitize-output",
|
|
@@ -5,7 +5,7 @@ class ContextGuard < Formula
|
|
|
5
5
|
|
|
6
6
|
desc "Local-first context guardrails for AI coding agents"
|
|
7
7
|
homepage "https://github.com/ictechgy/context-guard"
|
|
8
|
-
url "https://github.com/ictechgy/context-guard/archive/refs/tags/v0.4.
|
|
8
|
+
url "https://github.com/ictechgy/context-guard/archive/refs/tags/v0.4.7.tar.gz"
|
|
9
9
|
sha256 "REPLACE_WITH_RELEASE_TARBALL_SHA256"
|
|
10
10
|
license "Apache-2.0"
|
|
11
11
|
|
|
@@ -113,7 +113,7 @@ brief 모드는 코딩 에이전트가 군더더기를 줄이도록 요청하되
|
|
|
113
113
|
|
|
114
114
|
ContextGuard는 모델 토큰을 줄이기 위해 작업을 외부 AI 서비스로 전송하지 않습니다. 모든 헬퍼 명령은 로컬에서 동작합니다. 로컬 RAM/디스크 보관본은 다음에 보낼 컨텍스트를 줄이는 데 도움될 수 있지만 provider prompt cache를 대체하지 않습니다. Anthropic 배포나 청구 설명 전에는 공식 prompt caching/pricing 문서를 다시 확인하세요: https://docs.anthropic.com/en/build-with-claude/prompt-caching 및 https://platform.claude.com/docs/en/about-claude/pricing.
|
|
115
115
|
|
|
116
|
-
미래 learned,
|
|
116
|
+
미래 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만 shipped 상태이고, self-hosted metrics ledger는 `context-guard experiments plan self-hosted-metrics-ledger` dry-run preview만, local proxy는 `context-guard experiments plan local-proxy` localhost-only dry-run advisory plan만 shipped 상태이며 no listener/no traffic forwarding/no API-key persistence/read-only ledger boundary를 유지합니다. learned/synthetic compressor runtime·embedding·reranker·model call·replacement 생성, self-hosted KV/latent runtime 최적화, 실제 proxy forwarding runtime은 shipped가 아닙니다. multimodal OCR/crop은 `context-guard experiments plan visual-crop-ocr` dry-run planner만 shipped 상태이고 실제 OCR/crop runtime·스크린샷 캡처·이미지 파싱·외부 OCR/이미지 서비스 호출은 shipped가 아닙니다. 이 radar와 fixture는 provider가 측정한 matched-task 근거 없이 hosted API 절감을 주장하지 않습니다. Radar의 later-roadmap gate는 neural/semantic compression, trust-tiered injection-aware compression, context-diff compaction, local proxy constraint도 별도 미래 PR이 gate를 통과하기 전까지 experimental/non-shipped로 묶습니다.
|
|
117
117
|
|
|
118
118
|
교차 에이전트 규칙 스니펫은 권고 사항입니다. 대상 에이전트가 반드시 따른다고 보장할 수 없으므로, 절감 주장이 필요하면 실제 전후 동작을 직접 측정하세요.
|
|
119
119
|
|
|
@@ -119,7 +119,25 @@ These helpers reduce common sources of context bloat, but they do not guarantee
|
|
|
119
119
|
|
|
120
120
|
ContextGuard also does not send work to external AI providers to save model tokens. All helper commands run locally. Local RAM/disk receipts can reduce what you choose to send, but they do not replace a provider prompt cache. Before release or billing claims for Anthropic, recheck the official prompt-caching and pricing docs: https://docs.anthropic.com/en/build-with-claude/prompt-caching and https://platform.claude.com/docs/en/about-claude/pricing.
|
|
121
121
|
|
|
122
|
-
Future learned, multimodal, and self-hosted optimization ideas are tracked
|
|
122
|
+
Future learned, multimodal, and self-hosted optimization ideas are tracked in [`research/experimental-token-reduction-radar.md`](https://github.com/ictechgy/context-guard/blob/main/research/experimental-token-reduction-radar.md), with fixture-only starters in [`docs/experimental-benchmark-fixtures.md`](https://github.com/ictechgy/context-guard/blob/main/docs/experimental-benchmark-fixtures.md). ContextGuard ships dry-run planners/checkers for learned compression, self-hosted metrics ledger previews, and local-proxy advisory plans only; learned/synthetic compressor runtime, embeddings, rerankers, model calls, replacement generation, self-hosted KV/latent runtime optimization, and actual proxy forwarding runtime are not shipped. That radar and the fixtures do not claim hosted API savings without provider-measured matched-task evidence. The radar's later-roadmap gates also keep neural/semantic compression, trust-tiered injection-aware compression, context-diff compaction, and local proxy constraints experimental/non-shipped until a separate future PR satisfies those gates.
|
|
123
|
+
|
|
124
|
+
## Experimental opt-ins
|
|
125
|
+
|
|
126
|
+
Experimental lanes are default off. The registry is project-local metadata only; enabling an experiment records intent in `.context-guard/experiments.json` and does not activate stable runtime behavior by itself.
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
context-guard experiments list
|
|
130
|
+
context-guard experiments status --json
|
|
131
|
+
context-guard experiments plan context-diff-compaction --json < change.diff
|
|
132
|
+
context-guard experiments plan visual-crop-ocr --json --full-evidence-receipt <id> --crop-label <label> --crop-bounds 0,0,100,100 --image-size 800,600 --missed-context-note "outside crop omitted"
|
|
133
|
+
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
|
|
134
|
+
context-guard experiments plan self-hosted-metrics-ledger --json --latency-ms 123.5 --peak-memory-mb 2048 --quality-score 0.98
|
|
135
|
+
context-guard experiments plan local-proxy --json --bind-host 127.0.0.1 --target-host 127.0.0.1 --runtime-gate-ack
|
|
136
|
+
context-guard experiments enable output-receipt-trim --root .
|
|
137
|
+
context-guard experiments disable output-receipt-trim --root .
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
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`, and it can 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 self-hosted-metrics-ledger`, and `context-guard experiments plan local-proxy`. The visual planner is shipped only as a metadata/fixture review surface: OCR/crop runtime, screenshot capture, image parsing, and external OCR/image services are not shipped. The learned-compression checker is likewise a deny-by-default dry-run policy check: learned/synthetic compressor runtime, embeddings, rerankers, model calls, and replacement generation are not shipped. The self-hosted metrics planner emits a read-only ledger-compatible preview for explicit local/model-server latency, memory, quality, energy, throughput, and local-cost metrics; it does not write a ledger or permit hosted API token/cost savings claims. The local-proxy planner emits localhost-only advisory metadata only: it starts no listener, forwards no traffic, persists no API keys, writes no ledger, blocks non-local targets, and requires a separate future runtime gate before any forwarding implementation. `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.
|
|
123
141
|
|
|
124
142
|
Cross-agent rule snippets are advisory: the target agent may ignore them, so measure actual before/after behavior when you need a savings claim.
|
|
125
143
|
|
|
@@ -22,6 +22,7 @@ HELPER_SUBCOMMANDS: dict[str, tuple[str, ...]] = {
|
|
|
22
22
|
"doctor": ("context-guard-setup", "--verify"),
|
|
23
23
|
"audit": ("context-guard-audit",),
|
|
24
24
|
"diet": ("context-guard-diet",),
|
|
25
|
+
"experiments": ("context-guard-experiments",),
|
|
25
26
|
"scan": ("context-guard-diet", "scan"),
|
|
26
27
|
"trim-output": ("context-guard-trim-output",),
|
|
27
28
|
"trim": ("context-guard-trim-output",),
|
|
@@ -766,10 +766,20 @@ def cap_text(text: str, max_chars: int) -> tuple[str, bool]:
|
|
|
766
766
|
return text[:keep].rstrip() + marker, True
|
|
767
767
|
|
|
768
768
|
|
|
769
|
-
def query_content(
|
|
769
|
+
def query_content(
|
|
770
|
+
content: str,
|
|
771
|
+
*,
|
|
772
|
+
line_range: tuple[int, int] | None,
|
|
773
|
+
pattern: str | None,
|
|
774
|
+
max_lines: int,
|
|
775
|
+
full: bool = False,
|
|
776
|
+
) -> tuple[str, dict[str, object]]:
|
|
770
777
|
lines = content.splitlines(True)
|
|
771
778
|
selected: list[tuple[int, str]] = []
|
|
772
|
-
if
|
|
779
|
+
if full:
|
|
780
|
+
selected = list(enumerate(lines, start=1))
|
|
781
|
+
selector = {"type": "full"}
|
|
782
|
+
elif line_range is not None:
|
|
773
783
|
start, end = line_range
|
|
774
784
|
selected = list(enumerate(lines[start - 1 : end], start=start))
|
|
775
785
|
selector = {"type": "lines", "start": start, "end": end}
|
|
@@ -780,15 +790,18 @@ def query_content(content: str, *, line_range: tuple[int, int] | None, pattern:
|
|
|
780
790
|
selected = list(enumerate(lines[:max_lines], start=1))
|
|
781
791
|
selector = {"type": "head", "max_lines": max_lines}
|
|
782
792
|
total_matches = len(selected)
|
|
783
|
-
|
|
793
|
+
if not full:
|
|
794
|
+
selected = selected[:max_lines]
|
|
784
795
|
text = "".join(line for _idx, line in selected)
|
|
785
796
|
return text, {"selector": selector, "returned_lines": len(selected), "matched_lines": total_matches, "total_lines": len(lines)}
|
|
786
797
|
|
|
787
798
|
|
|
788
799
|
def get_command(args: argparse.Namespace) -> int:
|
|
789
800
|
artifact_id = args.artifact_id
|
|
790
|
-
|
|
801
|
+
full = bool(getattr(args, "full", False))
|
|
791
802
|
try:
|
|
803
|
+
if full and (args.lines or args.pattern or args.max_lines is not None):
|
|
804
|
+
raise ValueError("--full cannot be combined with --lines, --pattern, or --max-lines")
|
|
792
805
|
last_missing: FileNotFoundError | None = None
|
|
793
806
|
for directory in artifact_read_directories(args.dir):
|
|
794
807
|
try:
|
|
@@ -815,12 +828,14 @@ def get_command(args: argparse.Namespace) -> int:
|
|
|
815
828
|
actual_sha = hashlib.sha256(content.encode("utf-8", errors="replace")).hexdigest()
|
|
816
829
|
if actual_sha != expected_sha:
|
|
817
830
|
raise ValueError(f"artifact content checksum mismatch: {artifact_id}")
|
|
831
|
+
default_max_chars = max(DEFAULT_MAX_CHARS, expected_bytes) if full else DEFAULT_MAX_CHARS
|
|
832
|
+
max_chars = bounded_int(args.max_chars, default_max_chars, 1, MAX_MAX_BYTES)
|
|
818
833
|
line_range = parse_line_range(args.lines)
|
|
819
834
|
if line_range is not None and args.max_lines is None:
|
|
820
835
|
max_lines = min(line_range[1] - line_range[0] + 1, MAX_QUERY_LINES)
|
|
821
836
|
else:
|
|
822
837
|
max_lines = bounded_int(args.max_lines, DEFAULT_MAX_LINES, 1, MAX_QUERY_LINES)
|
|
823
|
-
selected, query = query_content(content, line_range=line_range, pattern=args.pattern, max_lines=max_lines)
|
|
838
|
+
selected, query = query_content(content, line_range=line_range, pattern=args.pattern, max_lines=max_lines, full=full)
|
|
824
839
|
selected, capped = cap_text(selected, max_chars)
|
|
825
840
|
except (FileNotFoundError, ValueError, OSError, json.JSONDecodeError) as exc:
|
|
826
841
|
print(f"context-guard-artifact: {exc}", file=sys.stderr)
|
|
@@ -895,7 +910,8 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
895
910
|
get.add_argument("--lines", help="1-based inclusive line range, e.g. 10:40")
|
|
896
911
|
get.add_argument("--pattern", help="literal substring filter")
|
|
897
912
|
get.add_argument("--max-lines", type=int, default=None)
|
|
898
|
-
get.add_argument("--
|
|
913
|
+
get.add_argument("--full", action="store_true", help="return full stored artifact content; cannot be combined with selectors")
|
|
914
|
+
get.add_argument("--max-chars", type=int, default=None)
|
|
899
915
|
get.add_argument("--json", action="store_true", help="emit query JSON with content")
|
|
900
916
|
get.set_defaults(func=get_command)
|
|
901
917
|
|