Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
7dc50d0
feat(edit): evaluate frozen constraints read-only
aimasteracc Aug 12, 2026
7d340e9
fix(edit): bind frozen constraint evidence
aimasteracc Aug 12, 2026
3d3c7f8
test(edit): preserve portable snapshot seams
aimasteracc Aug 12, 2026
22afcfa
fix(edit): close frozen constraint review gaps
aimasteracc Aug 12, 2026
bb1df70
fix(index): bind reusable capability scope
aimasteracc Aug 12, 2026
688e4d5
fix(edit): require exact constraint authority
aimasteracc Aug 12, 2026
5c7aad7
test(edit): preserve config capture seams
aimasteracc Aug 12, 2026
4b2a448
test(edit): emulate portable config evidence
aimasteracc Aug 12, 2026
e46914a
test(edit): complete portable oracle seams
aimasteracc Aug 12, 2026
813e1dc
fix(edit): harden read-only constraint authority
aimasteracc Aug 12, 2026
4c2847b
fix(edit): enforce bounded constraint reads
aimasteracc Aug 12, 2026
55f7e8d
fix(edit): bound response materialization
aimasteracc Aug 12, 2026
29fd21b
test(edit): scope read-only errors by platform
aimasteracc Aug 12, 2026
bab41f8
test(edit): isolate facade snapshot contract
aimasteracc Aug 12, 2026
b53c5ea
fix(edit): certify bounded cross-platform constraints
aimasteracc Aug 12, 2026
12c6db7
fix(edit): close portable constraint gaps
aimasteracc Aug 12, 2026
0cfb5d1
fix(edit): normalize portable index errors
aimasteracc Aug 12, 2026
a70fc6b
test(edit): align portable snapshot contracts
aimasteracc Aug 12, 2026
34f6473
fix(edit): normalize corrupt portable indexes
aimasteracc Aug 12, 2026
28f063c
fix(edit): close portable constraint authority
aimasteracc Aug 12, 2026
fe4815f
test(edit): make portable oracles cross-platform
aimasteracc Aug 12, 2026
178b52d
fix(edit): close frozen constraint authority
aimasteracc Aug 13, 2026
4c1d981
test(index): align portable Windows contracts
aimasteracc Aug 13, 2026
bb38b2d
fix(cache): close final constraint gates
aimasteracc Aug 13, 2026
f86af1d
fix(snapshot): close final review gates
aimasteracc Aug 13, 2026
313ea8f
fix(snapshot): close cross-platform review gates
aimasteracc Aug 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ TSA ships curated workflows under `.claude/skills/tsa-*/`:

Each skill ships an `allowed-tools` subset + procedure recipe + decision-surface schema, so the agent doesn't have to triage 8 tools on every question.

### 323 CLI flags
### 324 CLI flags

Superset of CodeGraph's CLI surface. Highlights:

Expand Down
2 changes: 1 addition & 1 deletion README_ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ TSA は `.claude/skills/tsa-*/` 下にキュレーション済みワークフロ

各 skill は `allowed-tools` ツール サブセット + 手順レシピ + 決定面スキーマを同梱し、エージェントは 8 個のツールから毎回選別する必要がありません。

### 323 の CLI フラグ
### 324 の CLI フラグ

CodeGraph の CLI の厳密な上位互換。主なもの:

Expand Down
2 changes: 1 addition & 1 deletion README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ TSA 在 `.claude/skills/tsa-*/` 下提供精选工作流:

每个 skill 都带 `allowed-tools` 工具子集 + 操作流程 + 决策面 schema,agent 不必在 8 个工具间反复挑选。

### 323 个 CLI flag
### 324 个 CLI flag

CodeGraph CLI 的严格超集。亮点:

Expand Down
4 changes: 2 additions & 2 deletions benchmarks/codegraph_compare/readme_claim_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
re.compile(r"13 言語は `?pipeline_registered|13 种语言为 `?pipeline_registered"),
re.compile(r"5 言語 gap|5 语言 gap"),
re.compile(r"1 ワークフロー|一个工作流"),
re.compile(r"\b323 CLI flags\b", re.IGNORECASE),
re.compile(r"323 の CLI フラグ|323 个 CLI flag", re.IGNORECASE),
re.compile(r"\b324 CLI flags\b", re.IGNORECASE),
re.compile(r"324 の CLI フラグ|324 个 CLI flag", re.IGNORECASE),
re.compile(r"\b(?:FTS5|BM25)\b"),
re.compile(r"\bE[0-4]\b"),
re.compile(r"\bE2E\b", re.IGNORECASE),
Expand Down
1 change: 1 addition & 0 deletions docs/CODEMAPS/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Categories of CLI surface:
- `--call-graph` — caller/callee graph

### Code Quality
- `--check-constraints [--constraints-read-only]` — evaluate architecture constraints; read-only mode forwards `persist=false` and never updates violation rows
- `--code-patterns` — smell detection
- `--refactor` — concrete refactor recipes
- `--outline` — hierarchical outline (package → class → method, no bodies)
Expand Down
2 changes: 1 addition & 1 deletion docs/api/facade-actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Reading the tables:
| --- | --- | --- | --- |
| `ast_diff` | `diff_snapshot_id`, `file_path`, `include_node_bodies`, `language`, `mode`, `new_file`, `new_ref`, `new_source`, `old_file`, `old_ref`, `old_source`, `output_format` | `success`*, `verdict`*, `agent_summary`, `error` + action payload | `--ast-diff` |
| `classify` | `diff_snapshot_id`, `file_path`, `hunk_cap`, `include_ast_nodes`, `language`, `mode`, `new_ref`, `new_source`, `old_ref`, `old_source`, `output_format` | `success`*, `verdict`*, `agent_summary`, `error` + action payload | `--semantic-classify` |
| `constraints` | `output_format`, `path_filter`, `severity_min` | `success`*, `verdict`*, `agent_summary`, `error` + action payload | `--check-constraints` |
| `constraints` | `diff_snapshot_id`, `output_format`, `path_filter`, `persist`, `scope_paths`, `severity_min` | `success`*, `verdict`*, `agent_summary`, `error` + action payload | `--check-constraints` |
| `guard` | `modification_type`*, `symbol`*, `file_path` | `success`*, `verdict`*, `agent_summary`, `error` + action payload | `--modification-guard` |
| `impact` | `agent_summary_only`, `capture_diff_snapshot`, `compact_only`, `include_tests`, `mode`, `output_format`, `pr_url`, `resource_profile`, `scope_mode`, `scope_paths` — `capture_diff_snapshot` is an explicit boolean producer available only to same-process POSIX consumers | `success`*, `verdict`*, `agent_summary`, `error` + action payload | `--change-impact` |
| `pr` | `include_call_graph`, `mode`, `output_format`, `pr_url` | `success`*, `verdict`*, `agent_summary`, `error` + action payload | `--pr-review` |
Expand Down
6 changes: 6 additions & 0 deletions docs/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -490,3 +490,9 @@ uv run tree-sitter-analyzer large_file.java --query-key methods --filter "public
# 4. Extract only the lines you need
uv run tree-sitter-analyzer large_file.java --partial-read --start-line 100 --end-line 150
```

### Constraint evaluation

`--check-constraints` evaluates the project architecture rules. Add
`--constraints-read-only` to forward `persist=false`, opening an existing cache
read-only and leaving its schema and violation rows unchanged.
7 changes: 6 additions & 1 deletion scripts/native_qualification_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,12 @@ def _cleanup_token_processes(
tracked.update(_token_processes(token, final_deadline))
alive = _live_processes(tracked)
if not alive:
return False
quiet_scans += 1
if quiet_scans == 2:
return True
time.sleep(min(0.02, max(0.0, final_deadline - time.monotonic())))
continue
quiet_scans = 0
_signal_group(proc, force=True)
for process in alive:
try:
Expand Down
4 changes: 2 additions & 2 deletions tests/contracts/test_language_support_inventory_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ def test_translated_readmes_reject_unregistered_quantitative_marketing(
(
"Python 3.10 以上",
"8 MCP ツール",
"### 323 の CLI フラグ",
"### 324 の CLI フラグ",
"22 言語プラグイン",
"13 は `pipeline_registered`",
"3 は `index_admitted`",
Expand All @@ -471,7 +471,7 @@ def test_translated_readmes_reject_unregistered_quantitative_marketing(
(
"需要 Python 3.10+",
"8 个 MCP 工具",
"### 323 个 CLI flag",
"### 324 个 CLI flag",
"22 个语言插件",
"13 个为 `pipeline_registered`",
"3 个为 `index_admitted`",
Expand Down
51 changes: 26 additions & 25 deletions tests/contracts/test_native_install_qualification.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,28 @@ def test_runner_late_detached_grandchild_cleanup_stress(tmp_path: Path) -> None:
_assert_late_spawn_cleanup(tmp_path, 10)


def test_cleanup_fallback_certifies_two_quiet_scans(
monkeypatch: pytest.MonkeyPatch,
) -> None:
import native_qualification_lib as owner

killed: list[bool] = []
process = type("Process", (), {"kill": lambda _self: killed.append(True)})()
scans = iter(([process], [], []))
forced: list[bool] = []
monkeypatch.setattr(owner, "_token_processes", lambda *_a, **_k: {})
monkeypatch.setattr(owner, "_live_processes", lambda _tracked: next(scans))
monkeypatch.setattr(
owner, "_signal_group", lambda _p, *, force: forced.append(force)
)
monkeypatch.setattr(owner.psutil, "wait_procs", lambda *_a, **_k: ([], []))
monkeypatch.setattr(owner.time, "sleep", lambda _seconds: None)

result = owner._cleanup_token_processes(object(), {}, "token", grace=0, force=0)

assert (result, forced, killed) == (True, [True], [True])


def test_runner_reports_cleanup_nonquiescence(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
Expand Down Expand Up @@ -463,31 +485,10 @@ def test_wheel_record_rejects_non_exact_or_injected_archive(

@pytest.mark.parametrize(
"mutation",
[
"valid",
"stage_false",
"extra_field",
"mcp_oracle",
"venv_provenance",
"direct_hash",
"direct_base64",
"snapshot_direct",
"transcript_error",
"transcript_missing",
"path_dotdot_posix",
"path_dotdot_windows",
"aggregate_extra",
"axis_digest",
"installed_member_hash",
"installed_member_size",
"installed_record_digest",
"installed_inventory",
"side_artifact",
"path_containment",
"zip_extra",
"zip_symlink",
"filename_metadata",
],
"valid stage_false extra_field mcp_oracle venv_provenance direct_hash direct_base64 "
"snapshot_direct transcript_error transcript_missing path_dotdot_posix path_dotdot_windows "
"aggregate_extra axis_digest installed_member_hash installed_member_size installed_record_digest "
"installed_inventory side_artifact path_containment zip_extra zip_symlink filename_metadata".split(),
)
def test_trusted_inline_verifier_rejects_candidate_forgery(
tmp_path: Path, mutation: str
Expand Down
77 changes: 44 additions & 33 deletions tests/integration/performance/test_mcp_performance.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,42 +525,53 @@ class TestMemoryOptimization:
async def test_memory_usage_optimization(
self, large_code_file, performance_monitor
):
"""メモリ使用量最適化の確認"""
tool = TableFormatTool()
"""Measure suppressed-output memory after one-time engine warm-up."""
import gc

output_root = Path(large_code_file).parent.resolve()
warmup_file = output_root / "warmup.py"
warmup_file.write_text("value = 1\n")
tool = TableFormatTool(str(output_root))
arguments = {
"file_path": large_code_file,
"format_type": "full",
"suppress_output": True,
"output_file": "test_output.json",
}
warm_arguments = {**arguments, "file_path": str(warmup_file)}

# Plugin/parser initialization is a one-time process cost whose RSS is
# scheduling-dependent under xdist. Warm it on a different file so the
# measured call still parses and formats the full large fixture.
warm_result = await tool.execute(warm_arguments)
assert warm_result["success"] is True
output_file = Path(warm_result["output_file_path"])
assert output_file.parent == output_root
output_file.unlink()
gc.collect()

# 初期メモリ使用量を記録
initial_memory = psutil.Process().memory_info().rss

performance_monitor.start_measurement()

# suppress_output=True でメモリ最適化を有効化
result = await tool.execute(
{
"file_path": large_code_file,
"format_type": "full",
"suppress_output": True,
"output_file": "test_output.json",
}
)

metrics = performance_monitor.end_measurement()
final_memory = psutil.Process().memory_info().rss

assert result["success"] is True

# メモリ使用量が適切に制御されていることを確認
memory_increase = (final_memory - initial_memory) / 1024 / 1024 # MB
assert memory_increase < 50, (
f"メモリ使用量増加が50MBを超過: {memory_increase:.2f}MB"
)

print(f"メモリ最適化実行時間: {metrics['execution_time']:.2f}秒")
print(f"メモリ使用量増加: {memory_increase:.2f}MB")

# 出力ファイルが作成されていることを確認
output_file = Path("test_output.json")
if output_file.exists():
output_file.unlink() # クリーンアップ
try:
result = await tool.execute(arguments)
metrics = performance_monitor.end_measurement()
final_memory = psutil.Process().memory_info().rss

assert result["success"] is True
output_file = Path(result["output_file_path"])
assert output_file.parent == output_root
assert output_file.exists() is True

memory_increase = (final_memory - initial_memory) / 1024 / 1024
assert memory_increase < 50, (
f"メモリ使用量増加が50MBを超過: {memory_increase:.2f}MB"
)

print(f"メモリ最適化実行時間: {metrics['execution_time']:.2f}秒")
print(f"メモリ使用量増加: {memory_increase:.2f}MB")
finally:
if output_file.exists():
output_file.unlink()


if __name__ == "__main__":
Expand Down
12 changes: 5 additions & 7 deletions tests/integration/test_diff_snapshot_capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def test_staged_snapshot_freezes_add_delete_rename_binary_and_multiple_files(
"gone.py",
"image.bin",
"impact.py",
"old.py",
"renamed.py",
]

Expand Down Expand Up @@ -245,19 +246,16 @@ def test_frozen_scope_inventory_does_not_admit_post_capture_mutation(


@POSIX_SNAPSHOT_TEST
def test_staged_symlink_records_unsupported_source_kind(tmp_path: Path) -> None:
# PR #1252 review thread 3746878582.
def test_staged_symlink_cannot_claim_shared_authoritative_generation(
tmp_path: Path,
) -> None:
root = _repo(tmp_path)
(root / "module.py").symlink_to("old.py")
_git(root, "add", "module.py")

result = snapshots.DiffSnapshotRegistry().create(str(root), "staged", [])

assert result["success"] is True
record = next(
item for item in result["changed_records"] if item["path"] == "module.py"
)
assert (record["new_kind"], record["new_mode"]) == ("symlink", "120000")
assert result == {"success": False, "error_code": "SOURCE_SCOPE_UNSAFE"}


def test_entry_parts_rejects_malformed_git_header() -> None:
Expand Down
Loading
Loading