Skip to content

Commit 416036e

Browse files
committed
Fix context packing for binary README assets
1 parent e80d329 commit 416036e

5 files changed

Lines changed: 163 additions & 10 deletions

File tree

PROJEKT.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ cargo check: green
3636
cargo test: green
3737
cargo clippy -- -D warnings: green
3838
cargo run --bin ctxt -- --json validate --run: green
39-
unit tests: 37 green
39+
unit tests: 38 green
4040
smoke tests: 83 green
4141
```
4242

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ cargo check: green
213213
cargo test: green
214214
cargo clippy -- -D warnings: green
215215
cargo run --bin ctxt -- --json validate --run: green
216-
unit tests: 37 green
216+
unit tests: 38 green
217217
smoke tests: 83 green
218218
```
219219

RELEASE_NOTES_v0.1.0.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# CompText CLI v0.1.0 Release Notes
2+
3+
Status: Release candidate, tag only after CI green.
4+
5+
CompText CLI `ctxt` is a local-first Rust CLI for deterministic, schema-oriented review workflow contracts. The v0.1.0 release candidate focuses on stable local evidence, explicit disabled gates, and contract-first startup behavior.
6+
7+
## Highlights
8+
9+
- Local-first Rust CLI `ctxt`.
10+
- Deterministic JSON contracts for machine-readable runtime state.
11+
- Startup, readiness, review workflow, and capability contracts.
12+
- Proposal, review, run, and validation artifact inspection contracts.
13+
- README brand assets for the v0.1.0 release-candidate presentation.
14+
- Binary README and media assets are excluded from context packing.
15+
- Offline/local-first safety boundary by default.
16+
17+
## Boundaries
18+
19+
- No MCP server implementation claim.
20+
- No external agent execution claim.
21+
- No provider gateway or live provider claim.
22+
- No proposal or review auto-apply claim.
23+
- No claim of hidden network activity.
24+
25+
## Validation Commands
26+
27+
```powershell
28+
cargo fmt --all --check
29+
cargo check
30+
cargo test
31+
cargo clippy -- -D warnings
32+
cargo run --bin ctxt -- --json validate --run
33+
```
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Phase 5e Binary Asset Context Pack Fix
2+
3+
PHASE: 5e README assets and v0.1.0 release-candidate preparation
4+
STATUS: success
5+
FILES_CHANGED:
6+
- `src/cli.rs`
7+
- `README.md`
8+
- `PROJEKT.md`
9+
- `RELEASE_NOTES_v0.1.0.md`
10+
- `reports/phase_5e_binary_asset_context_pack_fix.md`
11+
12+
COMMANDS_RUN:
13+
- `git fetch origin`
14+
- `git --no-pager status --short --branch`
15+
- `git --no-pager log --oneline -5`
16+
- `cargo fmt --all`
17+
- `cargo fmt --all --check`
18+
- `cargo check`
19+
- `cargo test`
20+
- `cargo clippy -- -D warnings`
21+
- `cargo run --bin ctxt -- --json validate --run`
22+
23+
VALIDATION:
24+
- `cargo fmt --all --check`: green
25+
- `cargo check`: green
26+
- `cargo test`: green, 38 unit tests and 83 smoke tests passed
27+
- `cargo clippy -- -D warnings`: green
28+
- `cargo run --bin ctxt -- --json validate --run`: green
29+
30+
ARTIFACTS:
31+
- Phase report: `reports/phase_5e_binary_asset_context_pack_fix.md`
32+
- Release notes draft: `RELEASE_NOTES_v0.1.0.md`
33+
34+
GIT:
35+
- Commit and push requested by user after green validation.
36+
- No tag or GitHub release created.
37+
38+
NETWORK:
39+
- allowed-external for `git fetch origin` under explicit user task instruction.
40+
- local-only for build, test, lint, and `ctxt` validation commands.
41+
42+
SECRETS:
43+
- No secret-bearing files were read.
44+
- No credentials, private keys, or environment dumps were printed or written.
45+
46+
POLICY_DECISIONS:
47+
- README and assets were preserved.
48+
- Binary/media/archive context-pack exclusions are generic, not hardcoded to `assets/brand/`.
49+
- Release prepared locally without tag or release publication.
50+
51+
RISKS:
52+
- Context-pack exclusion is extension-based. Unknown binary extensions may require future additions.
53+
54+
NEXT:
55+
- Commit and push the scoped fix if Git safety checks remain clean.

src/cli.rs

Lines changed: 73 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2142,6 +2142,22 @@ fn is_sensitive_context_path(path: &str) -> bool {
21422142
)
21432143
}
21442144

2145+
fn is_context_pack_excluded_path(path: &str) -> bool {
2146+
let normalized = path.replace('\\', "/");
2147+
let lower = normalized.to_ascii_lowercase();
2148+
let excluded_extensions = [
2149+
".exe", ".dll", ".pdb", ".png", ".jpg", ".jpeg", ".gif", ".webp", ".ico", ".pdf", ".zip",
2150+
".gz", ".tar", ".tgz", ".7z", ".rar", ".bin", ".wasm", ".so", ".dylib", ".class", ".jar",
2151+
".mp4", ".mov", ".avi", ".mp3", ".wav", ".flac", ".woff", ".woff2", ".ttf", ".otf",
2152+
];
2153+
2154+
lower == "cargo.lock"
2155+
|| is_sensitive_context_path(&normalized)
2156+
|| excluded_extensions
2157+
.iter()
2158+
.any(|extension| lower.ends_with(extension))
2159+
}
2160+
21452161
fn ensure_provider_network_allowed(
21462162
config: &Config,
21472163
profile: &ProviderProfile,
@@ -2198,12 +2214,7 @@ fn build_context_pack(task: &str) -> Result<ContextPack, String> {
21982214

21992215
for file in files {
22002216
let rel_path = normalize_path(&file);
2201-
if rel_path.ends_with(".exe")
2202-
|| rel_path.ends_with(".dll")
2203-
|| rel_path.ends_with(".pdb")
2204-
|| rel_path == "Cargo.lock"
2205-
|| is_sensitive_context_path(&rel_path)
2206-
{
2217+
if is_context_pack_excluded_path(&rel_path) {
22072218
continue;
22082219
}
22092220
let content = std::fs::read_to_string(&file)
@@ -2235,6 +2246,39 @@ fn build_context_pack(task: &str) -> Result<ContextPack, String> {
22352246
"*.pfx".to_string(),
22362247
"*key*".to_string(),
22372248
"*credential*".to_string(),
2249+
"*.exe".to_string(),
2250+
"*.dll".to_string(),
2251+
"*.pdb".to_string(),
2252+
"*.png".to_string(),
2253+
"*.jpg".to_string(),
2254+
"*.jpeg".to_string(),
2255+
"*.gif".to_string(),
2256+
"*.webp".to_string(),
2257+
"*.ico".to_string(),
2258+
"*.pdf".to_string(),
2259+
"*.zip".to_string(),
2260+
"*.gz".to_string(),
2261+
"*.tar".to_string(),
2262+
"*.tgz".to_string(),
2263+
"*.7z".to_string(),
2264+
"*.rar".to_string(),
2265+
"*.bin".to_string(),
2266+
"*.wasm".to_string(),
2267+
"*.so".to_string(),
2268+
"*.dylib".to_string(),
2269+
"*.class".to_string(),
2270+
"*.jar".to_string(),
2271+
"*.mp4".to_string(),
2272+
"*.mov".to_string(),
2273+
"*.avi".to_string(),
2274+
"*.mp3".to_string(),
2275+
"*.wav".to_string(),
2276+
"*.flac".to_string(),
2277+
"*.woff".to_string(),
2278+
"*.woff2".to_string(),
2279+
"*.ttf".to_string(),
2280+
"*.otf".to_string(),
2281+
"Cargo.lock".to_string(),
22382282
],
22392283
allowed_write_paths: vec![],
22402284
forbidden_actions: vec![],
@@ -5784,8 +5828,8 @@ fn handle_antigravity(subcommand: &str, action: Option<&str>) -> Result<(), Stri
57845828
#[cfg(test)]
57855829
mod tests {
57865830
use super::{
5787-
handle_benchmark, handle_validate, parse, BenchmarkArtifact, Command, Config, Defaults,
5788-
PolicyConfig, ProviderProfile,
5831+
build_context_pack, handle_benchmark, handle_validate, parse, BenchmarkArtifact, Command,
5832+
Config, Defaults, PolicyConfig, ProviderProfile,
57895833
};
57905834
use std::collections::HashMap;
57915835

@@ -6251,6 +6295,27 @@ mod tests {
62516295
assert_eq!(res, Ok(0));
62526296
}
62536297

6298+
#[test]
6299+
fn test_context_pack_skips_binary_readme_assets() {
6300+
let _guard = UNIT_TEST_LOCK.lock().unwrap();
6301+
let asset_dir = std::path::Path::new("assets/brand");
6302+
let asset_path = asset_dir.join("__ctxt_test_binary_asset.png");
6303+
let normalized_asset_path = "assets/brand/__ctxt_test_binary_asset.png";
6304+
6305+
let _ = std::fs::remove_file(&asset_path);
6306+
std::fs::create_dir_all(asset_dir).unwrap();
6307+
std::fs::write(&asset_path, [0xff, 0xd8, 0xff, 0x00]).unwrap();
6308+
6309+
let result = build_context_pack("binary asset skip");
6310+
let _ = std::fs::remove_file(&asset_path);
6311+
6312+
assert!(result.is_ok());
6313+
let context_pack = result.unwrap();
6314+
assert!(!context_pack
6315+
.included_files
6316+
.contains(&normalized_asset_path.to_string()));
6317+
}
6318+
62546319
#[test]
62556320
fn test_dummy_benchmark_artifact_shape() {
62566321
let providers = HashMap::new();

0 commit comments

Comments
 (0)