Core changes: - Add @defgroup/@ingroup to 1791 C2+ contracts (555 files) for HCA 128× pre-training DSA grouping - Add §0.1 Pre-Training Frequency matrix to semantics-core - Add §VIII Attention Architecture rules (ATTN_1-4) with MLA/CSA/HCA/DSA mechanics - Add @defgroup/@ingroup to canonical syntax (§II) and all contract examples Agent prompts (5 files): - Add ZERO-STATE RATIONALE with MLA/CSA/HCA/DSA compression mechanics - Add pre-training note: @RATIONALE/@REJECTED are in-context learned tags - svelte-coder: add missing #region contract, fix Svelte rule violations - python-coder/fullstack-coder: honor function contracts from speckit plan - qa-tester: add attention compliance audit (P3 ATTN_1-4 checks) Skills (6 files): - Translate all axiom_config descriptions to English - Fix doc_dirs to index .opencode/ and .specify/ - Deduplicate 5× complexity_rules → single global_tags catalog - Reduce semantics-svelte 591→485 lines (remove duplicate code blocks) - Fix semantics-testing: 'Short IDs' → 'Short hierarchical IDs' - Fix all examples: flat IDs → hierarchical Domain.Name format - Fix Svelte examples: replace raw Tailwind + <button> with semantic tokens + /ui Speckit workflow (commands + templates): - speckit.plan: add Function-Level Contracts for C3+ with @PRE/@POST/@TEST_EDGE - speckit.plan: add Attention Compliance Gate (ATTN_1-4 before contract generation) - speckit.tasks: add function contract inlining format (constraints in task description) - speckit.specify: load semantics-core for spec density rules - spec-template: add #region contract, @SEMANTICS grouping, hierarchical IDs - ux-reference-template: add #region wrapper - plan-template: add attention gate, @defgroup/@ingroup guidance - tasks-template: add attention audit + rebuild + orphan check tasks - constitution.md: translate to English, add Principle VIII (attention-optimized contracts) Reference modules rewritten (hierarchical IDs + full contracts): - Auth.Jwt: 6 child contracts with @RATIONALE/@REJECTED/@TEST_EDGE - Api.Auth: 5 endpoints with @TEST_EDGE + molecular CoT markers - Migration.Model: @defgroup Migration with 18 @ACTION + 6 @INVARIANT Scripts: - add_defgroup_ingroup.py: zero-risk additive @ingroup migration (1791 insertions) - migrate_hierarchical.py: flat→hierarchical ID dry-run analysis (792 contracts) - merge_prompts.py: merge all prompts/skills/commands into one review file Config: - axiom_config.yaml: 749→395 lines (-47%), English, doc_dirs include prompts - Fix test_datasets.py import collision (rename → test_datasets_routes.py) - Fix test_preview.py: SupersetClient→get_superset_client, AsyncMock, logger f-string
139 lines
6.0 KiB
Python
139 lines
6.0 KiB
Python
# #region AddDefgroupIngroup [C:3] [TYPE Module] [SEMANTICS migration,defgroup,ingroup]
|
|
# @defgroup Migration Add @defgroup/@ingroup — zero-risk additive operation.
|
|
# @BRIEF Inserts one line after each #region anchor. No renames. No deletions. Bottom-up insertion.
|
|
# @RATIONALE 97.9% of contracts lack @ingroup — the model's strongest pre-training DSA signal.
|
|
# @INVARIANT Anchor pairs untouched. @RELATION edges untouched. Business logic untouched.
|
|
|
|
import re, sys
|
|
from pathlib import Path
|
|
|
|
PATH_TO_DOMAIN = [
|
|
("frontend/src/lib/models/", "Models"), ("frontend/src/lib/components/ui/", "UI"),
|
|
("frontend/src/lib/components/translate/", "Translate"), ("frontend/src/lib/components/dashboard/", "Dashboard"),
|
|
("frontend/src/lib/components/llm/", "LLM"), ("frontend/src/lib/components/dataset-review/", "DatasetReview"),
|
|
("frontend/src/lib/components/settings/", "Settings"), ("frontend/src/lib/components/layout/", "Layout"),
|
|
("frontend/src/lib/components/assistant/", "Assistant"), ("frontend/src/lib/components/tasks/", "Tasks"),
|
|
("frontend/src/lib/components/", "Components"), ("frontend/src/lib/ui/", "UI"),
|
|
("frontend/src/lib/stores/", "Stores"), ("frontend/src/lib/api/", "ApiClient"),
|
|
("frontend/src/routes/", "Routes"), ("frontend/src/types/", "Types"),
|
|
("backend/src/api/routes/assistant/", "AssistantApi"), ("backend/src/api/routes/", "Api"),
|
|
("backend/src/core/task_manager/", "TaskManager"), ("backend/src/core/auth/", "Auth"),
|
|
("backend/src/core/migration/", "Migration"), ("backend/src/core/plugins/", "Plugin"),
|
|
("backend/src/core/", "Core"), ("backend/src/services/dataset_review/", "DatasetReview"),
|
|
("backend/src/services/", "Services"), ("backend/src/models/", "Models"),
|
|
("backend/src/schemas/", "Schemas"), ("backend/src/plugins/translate/", "Translate"),
|
|
("backend/src/plugins/llm_analysis/", "LLMAnalysis"), ("backend/src/plugins/git/", "Git"),
|
|
("backend/src/plugins/storage/", "Storage"), ("backend/src/plugins/", "Plugin"),
|
|
("backend/tests/", "Tests"),
|
|
]
|
|
|
|
SEMANTICS_TO_DOMAIN = {
|
|
"auth": "Auth", "login": "Auth", "token": "Auth", "migration": "Migration",
|
|
"dashboard": "Dashboard", "dataset": "Dataset", "translate": "Translate",
|
|
"translation": "Translate", "llm": "LLM", "git": "Git", "storage": "Storage",
|
|
"plugin": "Plugin", "task": "Tasks", "test": "Tests", "api": "Api", "ui": "UI",
|
|
"users": "Users", "roles": "Roles", "settings": "Settings", "profile": "Profile",
|
|
"reports": "Reports", "validation": "Validation", "backup": "Backup",
|
|
"mapper": "Mapper", "debug": "Debug", "assistant": "Assistant", "admin": "Admin",
|
|
"notification": "Notifications", "schedule": "Schedule", "logging": "Logging",
|
|
"indexing": "Index", "curation": "Curator", "semantic": "Semantic",
|
|
"screenshot": "Screenshot", "health": "Health",
|
|
}
|
|
|
|
ANCHOR_RE = re.compile(
|
|
r'^(\s*(?:#|//|<!--)\s*#region\s+(?P<id>[^\s\[\(]+)\s*\[[^\]]+\][^\n]*)', re.MULTILINE)
|
|
INGROUP_RE = re.compile(r'@ingroup\s', re.MULTILINE)
|
|
DEFGROUP_RE = re.compile(r'@defgroup\s', re.MULTILINE)
|
|
SEMANTICS_RE = re.compile(r'@SEMANTICS\s+([^\n]+)')
|
|
|
|
|
|
def find_files(root):
|
|
dirs = [root / d for d in ["backend/src", "frontend/src", "backend/tests"]]
|
|
return sorted({f for d in dirs if d.exists() for f in d.rglob("*.py")} |
|
|
{f for d in dirs if d.exists() for f in d.rglob("*.svelte")} |
|
|
{f for d in dirs if d.exists() for f in d.rglob("*.svelte.ts")})
|
|
|
|
|
|
def infer_domain(fp, semantics):
|
|
for kw in semantics:
|
|
kw = kw.strip().lower()
|
|
if kw in SEMANTICS_TO_DOMAIN:
|
|
return SEMANTICS_TO_DOMAIN[kw]
|
|
s = str(fp)
|
|
for prefix, domain in PATH_TO_DOMAIN:
|
|
if prefix in s:
|
|
return domain
|
|
return "Module"
|
|
|
|
|
|
def process(fp, dry_run=True):
|
|
content = fp.read_text(encoding="utf-8")
|
|
insertions = [] # (byte_position, text_to_insert)
|
|
|
|
for m in ANCHOR_RE.finditer(content):
|
|
anchor_line = m.group(0)
|
|
cid = m.group("id")
|
|
pos = m.end() # right after anchor line
|
|
|
|
# Skip checks
|
|
if cid.startswith("_"):
|
|
continue
|
|
if "[C:1]" in anchor_line:
|
|
continue
|
|
if "tests" in str(fp).lower() or "__tests__" in str(fp):
|
|
continue
|
|
|
|
# Check nearby text for existing @ingroup/@defgroup
|
|
nearby = content[pos:pos + 600]
|
|
if INGROUP_RE.search(nearby) or DEFGROUP_RE.search(nearby):
|
|
continue
|
|
|
|
sem = SEMANTICS_RE.search(content[m.start():pos + 600])
|
|
semantics = [s.strip() for s in sem.group(1).split(",")] if sem else []
|
|
domain = infer_domain(fp, semantics)
|
|
|
|
stripped = anchor_line.strip()
|
|
if stripped.startswith("<!--"):
|
|
prefix, suffix = "<!-- ", " -->"
|
|
elif stripped.startswith("//"):
|
|
prefix, suffix = "// ", ""
|
|
else:
|
|
prefix, suffix = "# ", ""
|
|
|
|
is_mod = "[TYPE Module]" in anchor_line or "[TYPE Class]" in anchor_line
|
|
line = f"\n{prefix}@defgroup {domain} Module group.{suffix}" if is_mod else f"\n{prefix}@ingroup {domain}{suffix}"
|
|
insertions.append((pos, line))
|
|
|
|
# Apply bottom-up
|
|
new_content = content
|
|
for pos, line in sorted(insertions, reverse=True):
|
|
new_content = new_content[:pos] + line + new_content[pos:]
|
|
|
|
if insertions and not dry_run:
|
|
fp.write_text(new_content, encoding="utf-8")
|
|
|
|
return {"file": str(fp), "added": len(insertions)}
|
|
|
|
|
|
def main():
|
|
dry = "--apply" not in sys.argv
|
|
root = Path.cwd()
|
|
for a in sys.argv[1:]:
|
|
if a.startswith("--root="):
|
|
root = Path(a.split("=", 1)[1])
|
|
print(f"=== @defgroup/@ingroup — {'DRY RUN' if dry else 'APPLY'} ===")
|
|
files = find_files(root)
|
|
total, results = 0, []
|
|
for f in files:
|
|
r = process(f, dry_run=dry)
|
|
if r["added"]:
|
|
results.append(r)
|
|
total += r["added"]
|
|
print(f"Files: {len(results)} Insertions: {total}")
|
|
if dry:
|
|
print("Run with --apply.")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
# #endregion AddDefgroupIngroup
|