auto-context-cli 1.0.6__tar.gz → 1.0.7__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.
Files changed (36) hide show
  1. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/PKG-INFO +3 -3
  2. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/README.md +2 -2
  3. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/pyproject.toml +1 -1
  4. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/commands/init_cmd.py +142 -2
  5. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/commands/update_cmd.py +19 -3
  6. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/main.py +4 -2
  7. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/AGENTS.template.md +5 -0
  8. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/GEMINI.template.md +5 -0
  9. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/maintain_context.template.md +5 -0
  10. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/rules/code-standards.md +6 -0
  11. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/rules/hub-satellite-architecture.md +2 -2
  12. auto_context_cli-1.0.7/src/auto_context/templates/rules/registry.json +226 -0
  13. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/.gitignore +0 -0
  14. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/LICENSE +0 -0
  15. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/__init__.py +0 -0
  16. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/commands/__init__.py +0 -0
  17. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/commands/import_cmd.py +0 -0
  18. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/commands/mcp.py +0 -0
  19. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/commands/memory.py +0 -0
  20. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/commands/scan_cmd.py +0 -0
  21. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/commands/share.py +0 -0
  22. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/config.py +0 -0
  23. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/scanner.py +0 -0
  24. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/security.py +0 -0
  25. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/context.local.template.md +0 -0
  26. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/context.template.md +0 -0
  27. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/mcp_config.template.json +0 -0
  28. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/profile.template.md +0 -0
  29. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/rule.template.md +0 -0
  30. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/rules/readme-docs-sync.md +0 -0
  31. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/rules/security-boundaries.md +0 -0
  32. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/skill.template.md +0 -0
  33. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/skills/browser-testing/SKILL.md +0 -0
  34. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/skills/docker-ops/SKILL.md +0 -0
  35. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/skills/git-workflow/SKILL.md +0 -0
  36. {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/skills/server-diagnostics/SKILL.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: auto-context-cli
3
- Version: 1.0.6
3
+ Version: 1.0.7
4
4
  Summary: Autonomous context & instruction manager for AI coding assistants
5
5
  Author: Arghya Biswas
6
6
  License: MIT
@@ -20,7 +20,7 @@ Description-Content-Type: text/markdown
20
20
 
21
21
  [![PyPI - Version](https://img.shields.io/pypi/v/auto-context-cli.svg?color=blue)](https://pypi.org/project/auto-context-cli/)
22
22
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/auto-context-cli.svg)](https://pypi.org/project/auto-context-cli/)
23
- [![GitHub Release](https://img.shields.io/github/v/release/Cyber-arghya/auto-context?color=green)](https://github.com/Cyber-arghya/auto-context/releases/tag/v1.0.6)
23
+ [![GitHub Release](https://img.shields.io/github/v/release/Cyber-arghya/auto-context?color=green)](https://github.com/Cyber-arghya/auto-context/releases/tag/v1.0.7)
24
24
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
25
25
  [![Platform](https://img.shields.io/badge/Platform-Windows%20%7C%20macOS%20%7C%20Linux%20WSL2-success.svg)](#-quick-one-line-install)
26
26
  [![AI Supported](https://img.shields.io/badge/AI%20Supported-Antigravity%20%7C%20Cursor%20%7C%20Claude%20Code%20%7C%20Copilot%20%7C%20Windsurf-orange.svg)](#-supported-ai-assistants)
@@ -83,7 +83,7 @@ Auto-Context supports both modern subcommands (`init-context <command>`) and sta
83
83
  | :--- | :--- | :--- |
84
84
  | `init-context init [DIR]` | `init-context [DIR]` | Scaffolds 5-tier context in active or specified directory. |
85
85
  | `init-context scan [DIR]` | `init-context --scan` | Stack-adaptive codebase scanner: generates satellites (.agents/context/). |
86
- | `init-context rule <name>` | `init-context -r <name>` | Scaffolds a new agent rule with YAML frontmatter. |
86
+ | `init-context rule <name>` | `init-context -r <name> [-a]` | Scaffolds a rule or appends to a domain with `registry.json` duplicate protection. |
87
87
  | `init-context skill <name>` | `init-context -s <name>` | Scaffolds a new agent skill directory with triggers & runbook. |
88
88
  | `init-context promote <name>` | — | Promotes local workspace rule/skill to Global Plugin & Central Memory. |
89
89
  | `init-context update` | — | Modular, non-breaking update for CLI, global plugin & system rules. |
@@ -6,7 +6,7 @@
6
6
 
7
7
  [![PyPI - Version](https://img.shields.io/pypi/v/auto-context-cli.svg?color=blue)](https://pypi.org/project/auto-context-cli/)
8
8
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/auto-context-cli.svg)](https://pypi.org/project/auto-context-cli/)
9
- [![GitHub Release](https://img.shields.io/github/v/release/Cyber-arghya/auto-context?color=green)](https://github.com/Cyber-arghya/auto-context/releases/tag/v1.0.6)
9
+ [![GitHub Release](https://img.shields.io/github/v/release/Cyber-arghya/auto-context?color=green)](https://github.com/Cyber-arghya/auto-context/releases/tag/v1.0.7)
10
10
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
11
11
  [![Platform](https://img.shields.io/badge/Platform-Windows%20%7C%20macOS%20%7C%20Linux%20WSL2-success.svg)](#-quick-one-line-install)
12
12
  [![AI Supported](https://img.shields.io/badge/AI%20Supported-Antigravity%20%7C%20Cursor%20%7C%20Claude%20Code%20%7C%20Copilot%20%7C%20Windsurf-orange.svg)](#-supported-ai-assistants)
@@ -69,7 +69,7 @@ Auto-Context supports both modern subcommands (`init-context <command>`) and sta
69
69
  | :--- | :--- | :--- |
70
70
  | `init-context init [DIR]` | `init-context [DIR]` | Scaffolds 5-tier context in active or specified directory. |
71
71
  | `init-context scan [DIR]` | `init-context --scan` | Stack-adaptive codebase scanner: generates satellites (.agents/context/). |
72
- | `init-context rule <name>` | `init-context -r <name>` | Scaffolds a new agent rule with YAML frontmatter. |
72
+ | `init-context rule <name>` | `init-context -r <name> [-a]` | Scaffolds a rule or appends to a domain with `registry.json` duplicate protection. |
73
73
  | `init-context skill <name>` | `init-context -s <name>` | Scaffolds a new agent skill directory with triggers & runbook. |
74
74
  | `init-context promote <name>` | — | Promotes local workspace rule/skill to Global Plugin & Central Memory. |
75
75
  | `init-context update` | — | Modular, non-breaking update for CLI, global plugin & system rules. |
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "auto-context-cli"
3
- version = "1.0.6"
3
+ version = "1.0.7"
4
4
  description = "Autonomous context & instruction manager for AI coding assistants"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -167,6 +167,10 @@ def init(
167
167
  for rule_file in (templates / "rules").glob("*.md"):
168
168
  _copy_if_missing(rule_file, rules_dest / rule_file.name, force=force, dry_run=dry_run)
169
169
 
170
+ reg_tmpl = templates / "rules" / "registry.json"
171
+ if reg_tmpl.exists():
172
+ _copy_if_missing(reg_tmpl, rules_dest / "registry.json", force=force, dry_run=dry_run)
173
+
170
174
  maintain_tmpl = templates / "maintain_context.template.md"
171
175
  if maintain_tmpl.exists():
172
176
  content = _render(maintain_tmpl, variables)
@@ -234,14 +238,116 @@ def init(
234
238
 
235
239
  # ── rule command ──────────────────────────────────────────────────────────────
236
240
 
241
+ def _load_registry(registry_file: Path) -> dict:
242
+ if registry_file.exists():
243
+ try:
244
+ import json
245
+ return json.loads(registry_file.read_text(encoding="utf-8"))
246
+ except Exception:
247
+ pass
248
+ tmpl = get_templates_dir() / "rules" / "registry.json"
249
+ if tmpl.exists():
250
+ try:
251
+ import json
252
+ return json.loads(tmpl.read_text(encoding="utf-8"))
253
+ except Exception:
254
+ pass
255
+ return {"version": "1.0.0", "domains": {}}
256
+
257
+
258
+ def _find_duplicate_rule(registry: dict, text_or_title: str) -> Optional[tuple[str, str, str]]:
259
+ import re
260
+ clean_query = re.sub(r"[^a-zA-Z0-9\s]", "", text_or_title).lower().strip()
261
+ query_words = set(w for w in clean_query.split() if len(w) > 3)
262
+
263
+ for d_key, domain in registry.get("domains", {}).items():
264
+ d_file = domain.get("file", f"{d_key}.md")
265
+ for r in domain.get("rules", []):
266
+ r_title = r.get("title", "")
267
+ r_id = r.get("id", "")
268
+ clean_title = re.sub(r"[^a-zA-Z0-9\s]", "", r_title).lower().strip()
269
+
270
+ if clean_query == clean_title or (len(clean_query) > 6 and clean_query in clean_title) or (len(clean_title) > 6 and clean_title in clean_query):
271
+ return d_key, r_title, d_file
272
+ if r_id and r_id in clean_query.replace(" ", "-"):
273
+ return d_key, r_title, d_file
274
+
275
+ r_keywords = set(k.lower() for k in r.get("keywords", []))
276
+ if query_words and len(query_words.intersection(r_keywords)) >= 2:
277
+ return d_key, r_title, d_file
278
+
279
+ return None
280
+
281
+
282
+ def _register_rule_in_registry(registry_file: Path, domain_key: str, rule_title: str, file_name: str) -> None:
283
+ import json
284
+ import re
285
+ from datetime import date
286
+
287
+ registry = _load_registry(registry_file)
288
+ if "domains" not in registry:
289
+ registry["domains"] = {}
290
+
291
+ if domain_key not in registry["domains"]:
292
+ registry["domains"][domain_key] = {
293
+ "file": file_name,
294
+ "name": domain_key.replace("-", " ").title(),
295
+ "description": f"Domain rules for {domain_key}",
296
+ "rules": []
297
+ }
298
+
299
+ clean_first_line = rule_title.strip().splitlines()[0].strip("* ").strip()
300
+ slug = re.sub(r"[^a-zA-Z0-9\s-]", "", clean_first_line).strip().lower().replace(" ", "-")
301
+ clean_words = [w for w in re.sub(r"[^a-zA-Z0-9\s]", "", clean_first_line).lower().split() if len(w) > 3]
302
+
303
+ existing_ids = [r.get("id") for r in registry["domains"][domain_key].get("rules", [])]
304
+ if slug not in existing_ids:
305
+ registry["domains"][domain_key]["rules"].append({
306
+ "id": slug,
307
+ "title": clean_first_line,
308
+ "keywords": clean_words
309
+ })
310
+ registry["last_updated"] = date.today().isoformat()
311
+ registry_file.parent.mkdir(parents=True, exist_ok=True)
312
+ registry_file.write_text(json.dumps(registry, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
313
+
314
+
315
+ def _append_guideline_to_file(dest_file: Path, text_to_append: str) -> None:
316
+ import re
317
+ content = dest_file.read_text(encoding="utf-8")
318
+ existing_nums = [int(m) for m in re.findall(r"(?m)^(\d+)\.\s+\*", content)]
319
+ next_num = (max(existing_nums) + 1) if existing_nums else 1
320
+
321
+ clean_guideline = text_to_append.strip()
322
+ if not re.match(r"^\d+\.\s+", clean_guideline):
323
+ if not clean_guideline.startswith("**"):
324
+ lines = clean_guideline.splitlines()
325
+ title = lines[0]
326
+ rest = lines[1:] if len(lines) > 1 else []
327
+ entry = f"{next_num}. **{title}**\n"
328
+ for r in rest:
329
+ entry += f" {r}\n"
330
+ else:
331
+ entry = f"{next_num}. {clean_guideline}\n"
332
+ else:
333
+ entry = f"{clean_guideline}\n"
334
+
335
+ if not content.endswith("\n"):
336
+ content += "\n"
337
+ content += entry
338
+ dest_file.write_text(content, encoding="utf-8")
339
+
340
+
237
341
  def new_rule(
238
342
  name: Annotated[str, typer.Argument(help="Rule name (e.g. code-standards).")],
239
343
  target: Annotated[Optional[Path], typer.Option("--target", "-t")] = None,
240
344
  global_: Annotated[bool, typer.Option("--global", "-g", help="Install into global plugin.")] = False,
241
345
  force: Annotated[bool, typer.Option("--force", "-f")] = False,
346
+ append: Annotated[bool, typer.Option("--append", "-a", help="Append guideline to existing rule domain.")] = False,
347
+ guideline: Annotated[Optional[str], typer.Option("--guideline", help="Guideline text to append to rule.")] = None,
242
348
  dry_run: Annotated[bool, typer.Option("--dry-run", "-d")] = False,
243
349
  ) -> None:
244
- """Scaffold a new agent rule file."""
350
+ """Scaffold a new agent rule file or append to an existing domain rule with duplicate guard."""
245
351
  clean_name = name.lower().replace(" ", "-").replace("_", "-").removesuffix(".md")
246
352
  title = clean_name.replace("-", " ").title()
247
353
 
@@ -251,9 +357,43 @@ def new_rule(
251
357
  else (target or Path.cwd()).resolve() / AGENTS_SUBDIR / "rules"
252
358
  )
253
359
  dest_file = dest_dir / f"{clean_name}.md"
360
+ registry_file = dest_dir / "registry.json"
254
361
 
255
362
  if dest_file.exists() and not force:
256
- console.print(f"[yellow][!] Rule already exists:[/] {dest_file}\n Use --force to overwrite.")
363
+ if append or guideline:
364
+ text_to_append = guideline or "New domain constraint and best practice."
365
+
366
+ # Check duplicate against registry
367
+ dup = _find_duplicate_rule(_load_registry(registry_file), text_to_append)
368
+ if dup:
369
+ dup_domain, dup_title, dup_file = dup
370
+ console.print(Panel(
371
+ f"[bold yellow]⚠️ Duplicate Rule Detected — Skipped![/]\n"
372
+ f"[white]The guideline '[cyan]{text_to_append}[/]' matches existing rule:\n"
373
+ f"[green]'{dup_title}'[/] inside [yellow]{dup_file}[/] (Domain: [cyan]{dup_domain}[/]).\n\n"
374
+ f"[dim]Registry checked: {registry_file}[/]",
375
+ border_style="yellow",
376
+ ))
377
+ return
378
+
379
+ if not dry_run:
380
+ _append_guideline_to_file(dest_file, text_to_append)
381
+ _register_rule_in_registry(registry_file, clean_name, text_to_append, dest_file.name)
382
+ if global_ and config.MEMORY_DIR.exists():
383
+ mem_dest = config.MEMORY_DIR / "rules" / f"{clean_name}.md"
384
+ if mem_dest.exists():
385
+ _append_guideline_to_file(mem_dest, text_to_append)
386
+ _register_rule_in_registry(config.MEMORY_DIR / "rules" / "registry.json", clean_name, text_to_append, dest_file.name)
387
+ console.print(Panel(
388
+ f"[bold green]✨ Rule Domain Updated & Registered![/]\n"
389
+ f"[yellow] Rule:[/] {clean_name}\n"
390
+ f"[cyan] File:[/] {dest_file}\n"
391
+ f"[cyan] Registry:[/] {registry_file}\n"
392
+ f"[green] Added:[/] {text_to_append}",
393
+ border_style="green",
394
+ ))
395
+ return
396
+ console.print(f"[yellow][!] Rule already exists:[/] {dest_file}\n Use --append (-a) with --guideline to add to this domain, or --force to overwrite.")
257
397
  raise typer.Exit(1)
258
398
 
259
399
  tmpl = get_templates_dir() / "rule.template.md"
@@ -237,10 +237,20 @@ def update_global_plugin() -> int:
237
237
  core_files = [
238
238
  ("plugin.json", plugin_dir / "plugin.json"),
239
239
  ("plugin/rules/AGENTS.md", rules_dir / "AGENTS.md"),
240
+ ("plugin/rules/code-standards.md", rules_dir / "code-standards.md"),
241
+ ("plugin/rules/security-boundaries.md", rules_dir / "security-boundaries.md"),
242
+ ("plugin/rules/hub-satellite-architecture.md", rules_dir / "hub-satellite-architecture.md"),
243
+ ("plugin/rules/readme-docs-sync.md", rules_dir / "readme-docs-sync.md"),
244
+ ("plugin/rules/registry.json", rules_dir / "registry.json"),
240
245
  ("plugin/skills/auto-context/SKILL.md", skills_dir / "SKILL.md"),
246
+ ("plugin/skills/browser-testing/SKILL.md", plugin_dir / "skills" / "browser-testing" / "SKILL.md"),
247
+ ("plugin/skills/docker-ops/SKILL.md", plugin_dir / "skills" / "docker-ops" / "SKILL.md"),
248
+ ("plugin/skills/git-workflow/SKILL.md", plugin_dir / "skills" / "git-workflow" / "SKILL.md"),
249
+ ("plugin/skills/server-diagnostics/SKILL.md", plugin_dir / "skills" / "server-diagnostics" / "SKILL.md"),
241
250
  ]
242
251
 
243
252
  for rel_path, dest_path in core_files:
253
+ dest_path.parent.mkdir(parents=True, exist_ok=True)
244
254
  url = f"{config.RAW_GITHUB_BASE}/{rel_path}"
245
255
  content = _download_text(url)
246
256
  if content:
@@ -252,10 +262,16 @@ def update_global_plugin() -> int:
252
262
  tmpl_dir = config.get_templates_dir()
253
263
  fallback_map = {
254
264
  "AGENTS.md": tmpl_dir / "AGENTS.template.md",
255
- "SKILL.md": tmpl_dir / "skill.template.md",
265
+ "SKILL.md": tmpl_dir / "skills" / dest_path.parent.name / "SKILL.md" if (tmpl_dir / "skills" / dest_path.parent.name / "SKILL.md").exists() else tmpl_dir / "skill.template.md",
266
+ "code-standards.md": tmpl_dir / "rules" / "code-standards.md",
267
+ "security-boundaries.md": tmpl_dir / "rules" / "security-boundaries.md",
268
+ "hub-satellite-architecture.md": tmpl_dir / "rules" / "hub-satellite-architecture.md",
269
+ "readme-docs-sync.md": tmpl_dir / "rules" / "readme-docs-sync.md",
270
+ "registry.json": tmpl_dir / "rules" / "registry.json",
256
271
  }
257
- if dest_path.name in fallback_map and fallback_map[dest_path.name].exists():
258
- shutil.copy2(fallback_map[dest_path.name], dest_path)
272
+ fb = fallback_map.get(dest_path.name)
273
+ if fb and fb.exists():
274
+ shutil.copy2(fb, dest_path)
259
275
  console.print(f" [green][✓] Restored from bundled template:[/] {dest_path.name}")
260
276
  updated_count += 1
261
277
 
@@ -54,6 +54,8 @@ def root(
54
54
  env: Annotated[Optional[str], typer.Option("--env", help="Environment variables (KEY=val,KEY2=val2).")] = None,
55
55
  global_: Annotated[bool, typer.Option("--global", "-g", help="Target global plugin scope.")] = False,
56
56
  force: Annotated[bool, typer.Option("--force", "-f", help="Overwrite existing files.")] = False,
57
+ append: Annotated[bool, typer.Option("--append", "-a", help="Append to existing domain rule.")] = False,
58
+ guideline: Annotated[Optional[str], typer.Option("--guideline", help="Guideline text to append to rule.")] = None,
57
59
  dry_run: Annotated[bool, typer.Option("--dry-run", "-d", help="Preview without writing.")] = False,
58
60
  scan: Annotated[bool, typer.Option("--scan", help="Run stack-adaptive scanner on target directory.")] = False,
59
61
  version: bool = typer.Option(False, "--version", "-v", help="Show version and exit."),
@@ -69,7 +71,7 @@ def root(
69
71
  try:
70
72
  v = pkg_version("auto-context")
71
73
  except Exception:
72
- v = "1.0.6"
74
+ v = "1.0.7"
73
75
  console.print(f"init-context v{v}")
74
76
  raise typer.Exit()
75
77
 
@@ -78,7 +80,7 @@ def root(
78
80
 
79
81
  # ── Legacy flag routing ────────────────────────────────────────────────────
80
82
  if new_rule:
81
- init_cmd.new_rule(name=new_rule, target=target, global_=global_, force=force, dry_run=dry_run)
83
+ init_cmd.new_rule(name=new_rule, target=target, global_=global_, force=force, append=append, guideline=guideline, dry_run=dry_run)
82
84
  return
83
85
 
84
86
  if new_skill:
@@ -45,3 +45,8 @@ Never blindly delete or truncate context:
45
45
  - `init-context -s <name> [-g]`: Create skill.
46
46
  - `init-context update`: Safely sync public rules and upstream capabilities (non-breaking).
47
47
  - `init-context memory push`: Push updates to central memory.
48
+
49
+ ### 7. First-Principles Gatekeeper: Idempotency, KISS, DRY & The Brutal Truth Filter
50
+ - **Strict Idempotency Proof ($f(f(x)) = f(x)$):** All code generation, filesystem operations, and context sync commands must be 100% idempotent. Running them once or 100 times must yield the exact same deterministic state without duplication or side-effects.
51
+ - **Modular, KISS & DRY:** Maintain clean separation of concerns. Prohibit copy-paste duplication, unnecessary abstractions, and monolithic bloat across all project code and context.
52
+ - **The Brutal Truth Filter:** Every idea, design proposal, or architectural suggestion must pass first-principles scrutiny. If an idea or approach fails "The Brutal Truth Filter" (adds needless complexity, breaks DRY/KISS, or solves the wrong problem), **immediately DROP the idea** and proactively notify the user with clear technical rationale instead of blindly building flawed requests.
@@ -45,3 +45,8 @@ Never blindly delete or truncate context:
45
45
  - `init-context -s <name> [-g]`: Create skill.
46
46
  - `init-context update`: Safely sync public rules and upstream capabilities (non-breaking).
47
47
  - `init-context memory push`: Push updates to central memory.
48
+
49
+ ### 7. First-Principles Gatekeeper: Idempotency, KISS, DRY & The Brutal Truth Filter
50
+ - **Strict Idempotency Proof ($f(f(x)) = f(x)$):** All code generation, filesystem operations, and context sync commands must be 100% idempotent. Running them once or 100 times must yield the exact same deterministic state without duplication or side-effects.
51
+ - **Modular, KISS & DRY:** Maintain clean separation of concerns. Prohibit copy-paste duplication, unnecessary abstractions, and monolithic bloat across all project code and context.
52
+ - **The Brutal Truth Filter:** Every idea, design proposal, or architectural suggestion must pass first-principles scrutiny. If an idea or approach fails "The Brutal Truth Filter" (adds needless complexity, breaks DRY/KISS, or solves the wrong problem), **immediately DROP the idea** and proactively notify the user with clear technical rationale instead of blindly building flawed requests.
@@ -46,3 +46,8 @@ Never blindly delete or truncate context:
46
46
  - `init-context scan`: Refresh stack-adaptive satellites (`routes.md`, `schema.md`, `gotchas.md`).
47
47
  - `init-context update`: Safely sync public rules and upstream capabilities (non-breaking).
48
48
  - `init-context memory push`: Push updates to central memory.
49
+
50
+ ### 7. First-Principles Gatekeeper: Idempotency, KISS, DRY & The Brutal Truth Filter
51
+ - **Strict Idempotency Proof ($f(f(x)) = f(x)$):** All code generation, filesystem operations, and context sync commands must be 100% idempotent. Running them once or 100 times must yield the exact same deterministic state without duplication or side-effects.
52
+ - **Modular, KISS & DRY:** Maintain clean separation of concerns. Prohibit copy-paste duplication, unnecessary abstractions, and monolithic bloat across all project code and context.
53
+ - **The Brutal Truth Filter:** Every idea, design proposal, or architectural suggestion must pass first-principles scrutiny. If an idea or approach fails "The Brutal Truth Filter" (adds needless complexity, breaks DRY/KISS, or solves the wrong problem), **immediately DROP the idea** and proactively notify the user with clear technical rationale instead of blindly building flawed requests.
@@ -22,3 +22,9 @@ Maintain readable, maintainable, modular, and type-safe codebases with clear err
22
22
  - Log actionable error messages that include relevant context (e.g. invalid inputs, resource identifiers).
23
23
  4. **Conventional Git Commits:**
24
24
  - Write semantic commit messages (`feat:`, `fix:`, `docs:`, `refactor:`, `chore:`).
25
+ 5. **Static Type Annotations & Null Safety:**
26
+ - Enforce explicit type annotations for public functions, parameters, and return types.
27
+ - Prohibit unchecked null / undefined dereferencing.
28
+ 6. **Named Constants Over Magic Values:**
29
+ - Replace literal strings and magic numbers with descriptive, uppercase module-level constants.
30
+ 7. **Immutable Data Structures**
@@ -23,8 +23,8 @@ Prevent monolithic context file bloat, eliminate token waste, ensure 100% idempo
23
23
  - User-written notes, secrets, and manual entries outside anchored zones must remain 100% untouched.
24
24
  - Check content hashes before disk writes to avoid unnecessary I/O.
25
25
 
26
- 3. **The Brutal Truth Filter (Zero Dead Logs):**
27
- - If an idea, log entry, or feature fails first-principles scrutiny, drop it immediately and inform the user.
26
+ 3. **The Brutal Truth Filter (Zero Dead Logs & Flawed Ideas):**
27
+ - If an idea, design approach, log entry, or feature proposal fails first-principles scrutiny, breaks KISS/DRY principles, or does not pass 'The Brutal Truth Filter', **immediately drop the idea and notify the user** with honest technical reasons.
28
28
  - Prohibit chronological bug cemeteries (`history.md` dumps of trivial solved bugs).
29
29
  - In their place, maintain **`gotchas.md`**: high-impact institutional knowledge, non-obvious architecture traps, port collisions, and edge-case invariants.
30
30
 
@@ -0,0 +1,226 @@
1
+ {
2
+ "version": "1.0.0",
3
+ "last_updated": "2026-11-02",
4
+ "description": "Registry of unique rules and guidelines to prevent duplicates and enforce domain consolidation.",
5
+ "domains": {
6
+ "code-standards": {
7
+ "file": "code-standards.md",
8
+ "name": "Code Quality & Architecture Standards",
9
+ "description": "Clean code, defensive programming, typing, naming, and error handling",
10
+ "rules": [
11
+ {
12
+ "id": "defensive-coding-early-return",
13
+ "title": "Defensive Coding & Early Return",
14
+ "keywords": [
15
+ "guard clauses",
16
+ "early return",
17
+ "nested indentation",
18
+ "input validation",
19
+ "defensive coding"
20
+ ]
21
+ },
22
+ {
23
+ "id": "clean-code-srp",
24
+ "title": "Clean Code & Self-Documenting Logic",
25
+ "keywords": [
26
+ "single responsibility",
27
+ "srp",
28
+ "clean code",
29
+ "variable names",
30
+ "docstrings"
31
+ ]
32
+ },
33
+ {
34
+ "id": "structured-error-handling",
35
+ "title": "Structured Error Handling",
36
+ "keywords": [
37
+ "exception handling",
38
+ "empty catch",
39
+ "error logging",
40
+ "try catch"
41
+ ]
42
+ },
43
+ {
44
+ "id": "conventional-git-commits",
45
+ "title": "Conventional Git Commits",
46
+ "keywords": [
47
+ "commit messages",
48
+ "feat",
49
+ "fix",
50
+ "docs",
51
+ "chore",
52
+ "refactor"
53
+ ]
54
+ },
55
+ {
56
+ "id": "static-type-annotations",
57
+ "title": "Static Type Annotations & Null Safety",
58
+ "keywords": [
59
+ "type hints",
60
+ "type annotations",
61
+ "null safety",
62
+ "typing",
63
+ "null pointer"
64
+ ]
65
+ },
66
+ {
67
+ "id": "named-constants-over-magic-values",
68
+ "title": "Named Constants Over Magic Values",
69
+ "keywords": [
70
+ "magic numbers",
71
+ "literal strings",
72
+ "constants",
73
+ "magic values"
74
+ ]
75
+ },
76
+ {
77
+ "id": "immutable-data-structures",
78
+ "title": "Immutable Data Structures",
79
+ "keywords": [
80
+ "immutable",
81
+ "data",
82
+ "structures"
83
+ ]
84
+ }
85
+ ]
86
+ },
87
+ "security-boundaries": {
88
+ "file": "security-boundaries.md",
89
+ "name": "Security Boundaries & Secret Safety",
90
+ "description": "Secret protection, API keys, sandbox isolation, and network exposure",
91
+ "rules": [
92
+ {
93
+ "id": "zero-hardcoded-secrets",
94
+ "title": "Zero Hardcoded Secrets",
95
+ "keywords": [
96
+ "api keys",
97
+ "passwords",
98
+ "tokens",
99
+ "private keys",
100
+ "secrets",
101
+ ".env"
102
+ ]
103
+ },
104
+ {
105
+ "id": "local-sandbox-test-data-isolation",
106
+ "title": "Local Sandbox Test Data Isolation",
107
+ "keywords": [
108
+ "context.local.md",
109
+ "mock credentials",
110
+ "dummy logins",
111
+ "test accounts",
112
+ "git-ignored"
113
+ ]
114
+ },
115
+ {
116
+ "id": "public-exposure-boundaries",
117
+ "title": "Public Exposure Boundaries",
118
+ "keywords": [
119
+ "port binding",
120
+ "127.0.0.1",
121
+ "localhost",
122
+ "exposure",
123
+ "tunneling"
124
+ ]
125
+ }
126
+ ]
127
+ },
128
+ "hub-satellite-architecture": {
129
+ "file": "hub-satellite-architecture.md",
130
+ "name": "Hub & Satellite Modular Architecture & Idempotency Proof",
131
+ "description": "Context budget, satelittes, deterministic idempotency, and gotchas invariants",
132
+ "rules": [
133
+ {
134
+ "id": "hub-satellite-token-budget",
135
+ "title": "Hub & Satellite Pattern (Strict Token Budget)",
136
+ "keywords": [
137
+ "context.md",
138
+ "satellites",
139
+ "routes.md",
140
+ "schema.md",
141
+ "gotchas.md",
142
+ "token budget"
143
+ ]
144
+ },
145
+ {
146
+ "id": "strict-idempotency-proof",
147
+ "title": "Strict Idempotency Proof",
148
+ "keywords": [
149
+ "idempotency",
150
+ "anchored blocks",
151
+ "re-running",
152
+ "deterministic",
153
+ "hash check"
154
+ ]
155
+ },
156
+ {
157
+ "id": "brutal-truth-filter",
158
+ "title": "The Brutal Truth Filter (Zero Dead Logs)",
159
+ "keywords": [
160
+ "gotchas.md",
161
+ "anti-patterns",
162
+ "dead logs",
163
+ "bug cemeteries",
164
+ "invariants"
165
+ ]
166
+ },
167
+ {
168
+ "id": "kiss-dry-heuristics",
169
+ "title": "KISS & DRY Heuristics",
170
+ "keywords": [
171
+ "convention heuristics",
172
+ "graceful degradation",
173
+ "lightweight scanners"
174
+ ]
175
+ }
176
+ ]
177
+ },
178
+ "readme-docs-sync": {
179
+ "file": "readme-docs-sync.md",
180
+ "name": "Mandatory README & Documentation Synchronization",
181
+ "description": "Documentation synchronization for CLI commands, options, and workflows",
182
+ "rules": [
183
+ {
184
+ "id": "zero-undocumented-features",
185
+ "title": "Zero Undocumented Features",
186
+ "keywords": [
187
+ "readme",
188
+ "documentation",
189
+ "docs sync",
190
+ "bengali guide",
191
+ "options table"
192
+ ]
193
+ },
194
+ {
195
+ "id": "clear-executable-instructions",
196
+ "title": "Clear & Executable Instructions",
197
+ "keywords": [
198
+ "executable commands",
199
+ "cli examples",
200
+ "options tables",
201
+ "syntax"
202
+ ]
203
+ },
204
+ {
205
+ "id": "safety-non-breaking-boundaries",
206
+ "title": "Safety & Non-Breaking Boundaries",
207
+ "keywords": [
208
+ "non-breaking",
209
+ "protection guarantees",
210
+ "custom rules preserve"
211
+ ]
212
+ },
213
+ {
214
+ "id": "release-version-alignment",
215
+ "title": "Release Version Alignment",
216
+ "keywords": [
217
+ "version bump",
218
+ "pyproject.toml",
219
+ "tags",
220
+ "release badges"
221
+ ]
222
+ }
223
+ ]
224
+ }
225
+ }
226
+ }