ckgraphify 0.1.2__tar.gz → 0.1.3__tar.gz
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.
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/PKG-INFO +1 -1
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/__main__.py +8 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/graph_main_backend.py +1 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/graph_main_frontend.py +1 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/graph_main_merge.py +8 -11
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/graph_main_trace.py +16 -14
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/pyproject.toml +1 -1
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/skill/skill.md +46 -12
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/LICENSE +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/MANIFEST.in +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/README.md +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/ckgraphify.egg-info/SOURCES.txt +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/__init__.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/analyze.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/benchmark.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/bridge_mtop.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/build.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/business_map.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/cache.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/callflow_html.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/cluster.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/dedup.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/detect.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/export.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/extract.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/global_graph.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/google_workspace.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/graph_main_html.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/hooks.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/ingest.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/llm.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/manifest.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/report.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/security.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/serve.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/transcribe.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/tree_html.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/validate.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/watch.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/graphify/wiki.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/setup.cfg +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/skill/__init__.py +0 -0
- {ckgraphify-0.1.2 → ckgraphify-0.1.3}/skill/skill-codex.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ckgraphify
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: AI coding assistant skill for Claude Code and Codex - graph-main boundary graphs, multi-repo call chains, business-map concepts, and business search
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Project-URL: Homepage, https://github.com/safishamsi/graphify
|
|
@@ -97,7 +97,15 @@ def _claude_plugin_root() -> Path | None:
|
|
|
97
97
|
return Path(raw).expanduser().resolve() if raw else None
|
|
98
98
|
|
|
99
99
|
|
|
100
|
+
def _claude_project_dir() -> Path | None:
|
|
101
|
+
raw = os.environ.get("CLAUDE_PROJECT_DIR", "").strip()
|
|
102
|
+
return Path(raw).expanduser().resolve() if raw else None
|
|
103
|
+
|
|
104
|
+
|
|
100
105
|
def _default_repos_root() -> Path:
|
|
106
|
+
project_dir = _claude_project_dir()
|
|
107
|
+
if project_dir is not None:
|
|
108
|
+
return project_dir / "repos"
|
|
101
109
|
plugin_root = _claude_plugin_root()
|
|
102
110
|
if plugin_root is not None:
|
|
103
111
|
return plugin_root / "repos"
|
|
@@ -1385,6 +1385,7 @@ def build_graph_main_backend(*, repo_root: Path, out_path: Path) -> GraphMainBac
|
|
|
1385
1385
|
"graph": {
|
|
1386
1386
|
"kind": "graph-main-backend",
|
|
1387
1387
|
"description": "Back-end focused graph (hsf/rest/mtop/dependency/metaq)",
|
|
1388
|
+
"repo_name": repo_root.name,
|
|
1388
1389
|
"mode": mode,
|
|
1389
1390
|
"sdk_detection": sdk,
|
|
1390
1391
|
},
|
|
@@ -1178,6 +1178,7 @@ def build_graph_main_frontend(*, repo_root: Path, out_path: Path) -> GraphMainFr
|
|
|
1178
1178
|
"graph": {
|
|
1179
1179
|
"kind": "graph-main-frontend",
|
|
1180
1180
|
"description": "Front-end graph (page/component/api)",
|
|
1181
|
+
"repo_name": repo_root.name,
|
|
1181
1182
|
"mode": mode,
|
|
1182
1183
|
"frontend_detection": detection,
|
|
1183
1184
|
},
|
|
@@ -62,24 +62,21 @@ def _edge_key(edge: dict) -> tuple[str, str, str, str]:
|
|
|
62
62
|
)
|
|
63
63
|
|
|
64
64
|
|
|
65
|
-
def _copy_node(repo: str,
|
|
65
|
+
def _copy_node(repo: str, node: dict) -> dict:
|
|
66
66
|
out = dict(node)
|
|
67
67
|
local_id = str(node.get("id", ""))
|
|
68
68
|
out["id"] = _node_key(repo, local_id)
|
|
69
69
|
out["local_id"] = local_id
|
|
70
70
|
out["repo"] = repo
|
|
71
|
-
out["repo_root"] = repo_root
|
|
72
|
-
out["graph_main_path"] = str(graph_path)
|
|
73
71
|
out.setdefault("main_kind", "unknown")
|
|
74
72
|
return out
|
|
75
73
|
|
|
76
74
|
|
|
77
|
-
def _copy_edge(repo: str,
|
|
75
|
+
def _copy_edge(repo: str, edge: dict) -> dict:
|
|
78
76
|
out = dict(edge)
|
|
79
77
|
out["source"] = _node_key(repo, edge.get("source", ""))
|
|
80
78
|
out["target"] = _node_key(repo, edge.get("target", ""))
|
|
81
79
|
out["repo"] = repo
|
|
82
|
-
out["graph_main_path"] = str(graph_path)
|
|
83
80
|
out["edge_scope"] = "intra_repo"
|
|
84
81
|
return out
|
|
85
82
|
|
|
@@ -94,7 +91,6 @@ def _shared_api_node(anchor: str, originals: list[dict]) -> dict:
|
|
|
94
91
|
"local_id": str(n.get("local_id", "")),
|
|
95
92
|
"source_file": str(n.get("source_file", "")),
|
|
96
93
|
"source_location": str(n.get("source_location", "")),
|
|
97
|
-
"graph_main_path": str(n.get("graph_main_path", "")),
|
|
98
94
|
}
|
|
99
95
|
for n in originals
|
|
100
96
|
]
|
|
@@ -192,6 +188,7 @@ def merge_graph_main_files(graph_paths: Iterable[Path], out_path: Path) -> Graph
|
|
|
192
188
|
edges: list[dict] = []
|
|
193
189
|
edge_seen: set[tuple[str, str, str, str]] = set()
|
|
194
190
|
repos: list[dict] = []
|
|
191
|
+
repo_roots: dict[str, str] = {}
|
|
195
192
|
id_to_node: dict[str, dict] = {}
|
|
196
193
|
canonical_index: dict[str, list[str]] = defaultdict(list)
|
|
197
194
|
kind_index: dict[str, dict[str, list[str]]] = defaultdict(lambda: defaultdict(list))
|
|
@@ -203,11 +200,10 @@ def merge_graph_main_files(graph_paths: Iterable[Path], out_path: Path) -> Graph
|
|
|
203
200
|
raise FileNotFoundError(f"graph-main not found: {path}")
|
|
204
201
|
data = _load_graph(path)
|
|
205
202
|
repo = _repo_from_path(path)
|
|
206
|
-
|
|
203
|
+
repo_root_abs = path.parent.parent
|
|
204
|
+
repo_roots[repo] = f"repos/{repo}"
|
|
207
205
|
repo_meta = {
|
|
208
206
|
"repo": repo,
|
|
209
|
-
"graph_path": str(path),
|
|
210
|
-
"repo_root": repo_root,
|
|
211
207
|
"kind": data.get("graph", {}).get("kind", ""),
|
|
212
208
|
"mode": data.get("graph", {}).get("mode", ""),
|
|
213
209
|
"nodes": len(data.get("nodes", [])),
|
|
@@ -216,7 +212,7 @@ def merge_graph_main_files(graph_paths: Iterable[Path], out_path: Path) -> Graph
|
|
|
216
212
|
repos.append(repo_meta)
|
|
217
213
|
|
|
218
214
|
for node in data.get("nodes", []):
|
|
219
|
-
copied = _copy_node(repo,
|
|
215
|
+
copied = _copy_node(repo, node)
|
|
220
216
|
nid = str(copied.get("id", ""))
|
|
221
217
|
nodes.append(copied)
|
|
222
218
|
id_to_node[nid] = copied
|
|
@@ -230,7 +226,7 @@ def merge_graph_main_files(graph_paths: Iterable[Path], out_path: Path) -> Graph
|
|
|
230
226
|
metaq_topic_index[topic_key].append(nid)
|
|
231
227
|
|
|
232
228
|
for edge in data.get("links", []):
|
|
233
|
-
copied = _copy_edge(repo,
|
|
229
|
+
copied = _copy_edge(repo, edge)
|
|
234
230
|
key = _edge_key(copied)
|
|
235
231
|
if key in edge_seen:
|
|
236
232
|
continue
|
|
@@ -433,6 +429,7 @@ def merge_graph_main_files(graph_paths: Iterable[Path], out_path: Path) -> Graph
|
|
|
433
429
|
"description": "Merged graph-main boundary graph with cross-repo semantic resolution edges",
|
|
434
430
|
"generated_at": report["generated_at"],
|
|
435
431
|
"repo_count": len(repos),
|
|
432
|
+
"repo_roots": repo_roots,
|
|
436
433
|
"repos": repos,
|
|
437
434
|
},
|
|
438
435
|
"nodes": nodes,
|
|
@@ -24,10 +24,11 @@ _TRACE_RELS = {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def _load_graph(path: Path) -> tuple[list[dict], list[dict]]:
|
|
27
|
+
def _load_graph(path: Path) -> tuple[list[dict], list[dict], dict[str, str]]:
|
|
28
28
|
data = json.loads(path.read_text(encoding="utf-8"))
|
|
29
29
|
links = data.get("links", data.get("edges", []))
|
|
30
|
-
|
|
30
|
+
repo_roots = data.get("graph", {}).get("repo_roots", {})
|
|
31
|
+
return list(data.get("nodes", [])), list(links), repo_roots
|
|
31
32
|
|
|
32
33
|
|
|
33
34
|
def _norm(v: object) -> str:
|
|
@@ -96,8 +97,9 @@ def _source_ref(node: dict) -> str:
|
|
|
96
97
|
return source_file or source_location or "-"
|
|
97
98
|
|
|
98
99
|
|
|
99
|
-
def _append_source_summary(lines: list[str], ordered_node_ids: list[str], by_id: dict[str, dict]) -> None:
|
|
100
|
+
def _append_source_summary(lines: list[str], ordered_node_ids: list[str], by_id: dict[str, dict], repo_roots: dict[str, str] | None = None) -> None:
|
|
100
101
|
lines.extend(["", "Sources:"])
|
|
102
|
+
rr = repo_roots or {}
|
|
101
103
|
for node_id in ordered_node_ids:
|
|
102
104
|
node = by_id[node_id]
|
|
103
105
|
lines.append(f"- {_node_text(node)}")
|
|
@@ -108,16 +110,16 @@ def _append_source_summary(lines: list[str], ordered_node_ids: list[str], by_id:
|
|
|
108
110
|
source_file = str(origin.get("source_file") or "")
|
|
109
111
|
source_location = str(origin.get("source_location") or "")
|
|
110
112
|
ref = f"{source_file}:{source_location}" if source_file and source_location else (source_file or source_location or "-")
|
|
111
|
-
|
|
113
|
+
root = rr.get(repo, "")
|
|
114
|
+
full_ref = f"{root}/{ref}" if root else ref
|
|
115
|
+
lines.append(f" origin: {repo} {full_ref}")
|
|
112
116
|
else:
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if graph_path:
|
|
120
|
-
lines.append(f" graph_main: {graph_path}")
|
|
117
|
+
repo = str(node.get("repo", ""))
|
|
118
|
+
root = rr.get(repo, "")
|
|
119
|
+
ref = _source_ref(node)
|
|
120
|
+
full_ref = f"{root}/{ref}" if root and ref != "-" else ref
|
|
121
|
+
lines.append(f" repo: {repo}")
|
|
122
|
+
lines.append(f" file: {full_ref}")
|
|
121
123
|
|
|
122
124
|
|
|
123
125
|
def _matches(node: dict, query: str, *, kinds: set[str] | None = None) -> bool:
|
|
@@ -179,7 +181,7 @@ def trace_graph_main(
|
|
|
179
181
|
prefer_repos: list[str] | tuple[str, ...] | set[str] | None = None,
|
|
180
182
|
exclude_repos: list[str] | tuple[str, ...] | set[str] | None = None,
|
|
181
183
|
) -> str:
|
|
182
|
-
nodes, links = _load_graph(graph_path)
|
|
184
|
+
nodes, links, repo_roots = _load_graph(graph_path)
|
|
183
185
|
by_id = {str(n.get("id", "")): n for n in nodes}
|
|
184
186
|
start = _pick_node(
|
|
185
187
|
nodes,
|
|
@@ -318,5 +320,5 @@ def trace_graph_main(
|
|
|
318
320
|
else:
|
|
319
321
|
walk(start_id, 0, {start_id}, "")
|
|
320
322
|
if include_sources:
|
|
321
|
-
_append_source_summary(lines, ordered_node_ids, by_id)
|
|
323
|
+
_append_source_summary(lines, ordered_node_ids, by_id, repo_roots)
|
|
322
324
|
return "\n".join(lines)
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ckgraphify"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.3"
|
|
8
8
|
description = "AI coding assistant skill for Claude Code and Codex - graph-main boundary graphs, multi-repo call chains, business-map concepts, and business search"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -6,6 +6,18 @@ trigger: /ckgraphify
|
|
|
6
6
|
|
|
7
7
|
# ckgraphify Skill
|
|
8
8
|
|
|
9
|
+
## Prerequisites
|
|
10
|
+
|
|
11
|
+
Before running any `graphify` command, ensure the CLI is available. Run this check once per session:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
command -v graphify >/dev/null 2>&1 || python3 -m pip install ckgraphify 2>/dev/null || true
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
If the install fails silently, tell the user to run `pip install ckgraphify` manually.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
9
21
|
ckgraphify helps users ask business questions without knowing exact graph node names.
|
|
10
22
|
|
|
11
23
|
The public API is `/ckgraphify ...`. Treat it as an assistant API: translate it into `graphify` CLI calls, graph inspection, focused code reading, or a learn candidate patch workflow as needed.
|
|
@@ -52,15 +64,27 @@ Show this API briefly.
|
|
|
52
64
|
## Execution Defaults
|
|
53
65
|
|
|
54
66
|
- `--path` can point to a workspace, repos root, repo list, or a merged graph JSON. Resolve it before running CLI commands.
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
67
|
+
- Two root directories:
|
|
68
|
+
- `${CLAUDE_PLUGIN_ROOT}` — installed plugin directory (graph data, map, evidence).
|
|
69
|
+
- `${CLAUDE_PROJECT_DIR}` — the project that installed the plugin (repos, pypi source, docs).
|
|
70
|
+
- Graph and business map (read/write):
|
|
58
71
|
- Default business map is `${CLAUDE_PLUGIN_ROOT}/graphify-out/business-map.json`.
|
|
72
|
+
- Default evidence shadow table is `${CLAUDE_PLUGIN_ROOT}/graphify-out/business-map-evidence.json`.
|
|
59
73
|
- Default merged graph is `${CLAUDE_PLUGIN_ROOT}/graphify-out/graph-hc.json`.
|
|
60
|
-
|
|
61
|
-
- Default
|
|
62
|
-
-
|
|
63
|
-
-
|
|
74
|
+
- Repos (code reading, main-graph generation):
|
|
75
|
+
- Default repos root is `${CLAUDE_PROJECT_DIR}/repos`.
|
|
76
|
+
- Each repo's graph-main output is `${CLAUDE_PROJECT_DIR}/repos/<repo>/graphify-out/graph-main.json`.
|
|
77
|
+
- Docs and policies (read-only, bundled with pypi source):
|
|
78
|
+
- `${CLAUDE_PROJECT_DIR}/ckgraphify/docs/business-map-policy.md`
|
|
79
|
+
- Sync: after writing to `${CLAUDE_PLUGIN_ROOT}/graphify-out/`, sync changes back to the project source:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
cp "${CLAUDE_PLUGIN_ROOT}/graphify-out/business-map.json" "${CLAUDE_PROJECT_DIR}/claude-plugin/graphify-out/business-map.json"
|
|
83
|
+
cp "${CLAUDE_PLUGIN_ROOT}/graphify-out/business-map-evidence.json" "${CLAUDE_PROJECT_DIR}/claude-plugin/graphify-out/business-map-evidence.json"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
- If `${CLAUDE_PLUGIN_ROOT}` is missing, report that the Claude plugin environment is not active.
|
|
87
|
+
- If `${CLAUDE_PROJECT_DIR}` is missing, report that repos and docs are not available for code reading.
|
|
64
88
|
- Default depth: `10`.
|
|
65
89
|
- Default answer: concise business result first, evidence second, gaps last.
|
|
66
90
|
- If required inputs are missing and cannot be inferred from files, ask one short clarification.
|
|
@@ -76,8 +100,8 @@ graphify business-lint --map <map>
|
|
|
76
100
|
graphify business-validate --map <map> --graph <graph>
|
|
77
101
|
graphify business-trace --map <map> --graph <graph> --concept <concept> --scenario <scenario> --flow <flow> --max-depth <n> --sources
|
|
78
102
|
graphify main-trace --graph <graph> --from <exact-node> --api <api> --max-depth <n> --sources --prefer-repo <repo> --exclude-repo <repo>
|
|
79
|
-
graphify main-graph "${
|
|
80
|
-
graphify merge-main-graphs "${
|
|
103
|
+
graphify main-graph "${CLAUDE_PROJECT_DIR}/repos/<repo>" --out "${CLAUDE_PROJECT_DIR}/repos/<repo>/graphify-out/graph-main.json"
|
|
104
|
+
graphify merge-main-graphs "${CLAUDE_PROJECT_DIR}/repos/<repo-a>/graphify-out/graph-main.json" "${CLAUDE_PROJECT_DIR}/repos/<repo-b>/graphify-out/graph-main.json" --out "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph-hc.json"
|
|
81
105
|
```
|
|
82
106
|
|
|
83
107
|
## Graph Scope
|
|
@@ -86,6 +110,15 @@ Treat the merged graph as business navigation, not as a complete execution trace
|
|
|
86
110
|
|
|
87
111
|
Do not expect `graph-hc.json` or other merged graphs to describe every parameter, response field, extension point, or method-local branch. That level of detail would make the graph too large and noisy. When a question depends on field-level or parameter-level behavior, first use `main-trace` and source filepaths to land on the right code, then read the relevant implementation directly.
|
|
88
112
|
|
|
113
|
+
### File path convention
|
|
114
|
+
|
|
115
|
+
Merged graphs store source paths as **relative paths** per repo. To resolve the full path for code reading:
|
|
116
|
+
|
|
117
|
+
- `graph.repo_roots` maps each repo name to its relative root, e.g. `{"p": "repos/p", "ele-newretail-drug": "repos/ele-newretail-drug"}`.
|
|
118
|
+
- Each node has `repo` (repo name) and `source_file` (relative to the repo root).
|
|
119
|
+
- Full path = `${CLAUDE_PROJECT_DIR}` + `/` + `repo_roots[node.repo]` + `/` + `node.source_file`.
|
|
120
|
+
- `main-trace --sources` already outputs resolved paths in `repos/<repo>/<file>` format.
|
|
121
|
+
|
|
89
122
|
Missing field-level graph evidence is not automatically a graph defect. Classify it as one of:
|
|
90
123
|
|
|
91
124
|
- graph navigation succeeded, code reading verified the detail;
|
|
@@ -113,15 +146,16 @@ Search discipline:
|
|
|
113
146
|
For `/ckgraphify learn`:
|
|
114
147
|
|
|
115
148
|
1. Require concept, scenario, repos, graph, map, and out.
|
|
116
|
-
2. Read
|
|
149
|
+
2. Read `${CLAUDE_PROJECT_DIR}/ckgraphify/docs/business-map-policy.md`; every map iteration must follow it or explicitly report the conflict.
|
|
117
150
|
3. Read existing map scenarios, flows, gaps, accepted gaps, verification scopes, and `search_constraints`.
|
|
118
151
|
4. Search graph nodes with aliases, keywords, page/API names, HSF names, and repo hints.
|
|
119
152
|
5. Run `main-trace` on promising graph matches.
|
|
120
153
|
6. Validate important links in code, especially when the answer depends on response fields, request parameters, extension points, or method-local branching.
|
|
121
|
-
7. For a simple branch, write a candidate patch to `--out` with scenario-level anchors, trace hints, verification scope, boundaries, and remaining gaps. Keep detailed source evidence in
|
|
154
|
+
7. For a simple branch, write a candidate patch to `--out` with scenario-level anchors, trace hints, verification scope, boundaries, and remaining gaps. Keep detailed source evidence in `${CLAUDE_PLUGIN_ROOT}/graphify-out/business-map-evidence.json`, not in `business-map.json`.
|
|
122
155
|
8. For a complex branch, write one scenario with `flows`; each flow may have `id`, `name`, `status`, `summary`, `verification_scope`, `anchors`, `trace_hints`, `gaps`, and `accepted_gaps`. Keep `business-map.json` compact; use the evidence shadow table for source proof.
|
|
123
156
|
9. Do not split a user's named complex scenario into multiple top-level scenarios unless the user asks for that model.
|
|
124
157
|
10. Run `business-lint` and `business-validate`; run `business-trace` if hints are usable.
|
|
158
|
+
11. After writing to `${CLAUDE_PLUGIN_ROOT}/graphify-out/`, sync changes back to `${CLAUDE_PROJECT_DIR}/claude-plugin/graphify-out/`.
|
|
125
159
|
|
|
126
160
|
## Answer Contract
|
|
127
161
|
|
|
@@ -140,7 +174,7 @@ Keep graph-main schema details, dependency extraction rules, and low-level branc
|
|
|
140
174
|
## Guardrails
|
|
141
175
|
|
|
142
176
|
- Do not write business semantics into `graph-main.json`.
|
|
143
|
-
- Before changing `business-map.json`, read
|
|
177
|
+
- Before changing `business-map.json`, read `${CLAUDE_PROJECT_DIR}/ckgraphify/docs/business-map-policy.md`; follow it or state the conflict.
|
|
144
178
|
- Use `scenario.flows[]` for sub-links inside one complex business scene, such as landing page purchase/refund/benefit branches.
|
|
145
179
|
- Keep `business-map.json` as a search/trace index. Do not add long `evidence` arrays there; put audit proof in `graphify-out/business-map-evidence.json`.
|
|
146
180
|
- Use `gaps` for active unknowns and `accepted_gaps` for known boundaries with a stop rule.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|