# Handoff Report: Investigation of Hygiene Audit Failure & `.agents` Exclusion

**Agent**: `explorer_orch7_1`  
**Working Directory**: `c:\Projects\FreeExile\.agents\teamwork\explorer_orch7_1`  
**Parent**: `orchestrator_7` (`d9c449d5-0493-487f-993e-5eb085ae9740`)  
**Timestamp**: 2026-10-01T02:25:00Z  
**Type**: Hard Handoff (Investigation Complete)

---

## 1. Observation

### 1.1. Verbatim Error & Quality Gate Failure
From `.agents\teamwork\orchestrator_6\GATE_STATUS.md` (lines 13–14):
```markdown
Gate Result: **FAIL** (challenger_m3_1 REQUEST_CHANGES)
- Reason: `python tools/lint/check_code_and_doc_hygiene.py --strict` failed with exit code 1 because `.agents\teamwork\reviewer_m1_2\adversarial_tests.py` (594 lines > 500 lines) was scanned. The `.agents` directory is metadata/subagent workspace and should either have `.agents` added to `EXCLUDE_DIRS` in `tools/lint/check_code_and_doc_hygiene.py` or the rogue test file in metadata removed.
```

When reproducing the failure by running `check_code_and_doc_hygiene.py` with `.agents` unexcluded:
```
[!] PHÁT HIỆN 1 FILE VI PHẠM HARD CAP (ERROR):
  ❌ [CODE] .agents\teamwork\reviewer_m1_2\adversarial_tests.py (594 dòng) -> Vượt quá Hard Cap (594 > 500 dòng). Bắt buộc tách module, catalog hoặc DTOs!

[*] CẢNH BÁO 5 FILE VƯỢT SOFT CAP (WARNING) TRONG .agents:
  ⚠️ [DOC] .agents\teamwork\explorer_m1_fix_1\handoff.md (406 dòng)
  ⚠️ [DOC] .agents\teamwork\explorer_m1_progression_2\report.md (486 dòng)
  ⚠️ [DOC] .agents\teamwork\explorer_m2_2\handoff.md (470 dòng)
  ⚠️ [DOC] .agents\teamwork\explorer_survey_i18n_1\handoff.md (441 dòng)
  ⚠️ [CODE] .agents\teamwork\reviewer_m1_2\adversarial_tests.py (594 dòng)

================================================================================
❌ KẾT QUẢ: PHÁT HIỆN FILE VI PHẠM QUY CHUẨN ĐỘ DÀI & MODULE HÓA!
================================================================================
Exit Code: 1
```

### 1.2. Traversal Logic & `EXCLUDE_DIRS` in `tools/lint/check_code_and_doc_hygiene.py`
In `tools/lint/check_code_and_doc_hygiene.py`:

- **Directory Traversal** (lines 259–273):
  ```python
  for dirpath, dirnames, filenames in os.walk(root_dir):
      # Prune excluded directories in-place
      dirnames[:] = [d for d in dirnames if d not in EXCLUDE_DIRS]

      for filename in filenames:
          ext = os.path.splitext(filename)[1].lower()
          if ext not in {".py", ".ts", ".js", ".cpp", ".h", ".hpp", ".md"}:
              continue

          full_path = os.path.join(dirpath, filename)
          rel_path = os.path.relpath(full_path, root_dir)

          if is_excluded(full_path, filename):
              continue
  ```
- **Exclusion Filter** (lines 108–117):
  ```python
  def is_excluded(path: str, filename: str) -> bool:
      if filename in EXCLUDE_FILES:
          return True
      if filename.endswith("_pb2.py") or filename.endswith("_pb2.pyi"):
          return True
      parts = os.path.normpath(path).split(os.sep)
      for part in parts:
          if part in EXCLUDE_DIRS:
              return True
      return False
  ```
- **Threshold Definitions** (lines 58–73):
  ```python
  CODE_SOFT_CAP = 350
  CODE_HARD_CAP = 500
  DOC_SOFT_CAP = 400
  DOC_HARD_CAP = 600
  FUNCTION_HARD_CAP = 50
  ```
- **Committed `EXCLUDE_DIRS` Set** (commit `3be7f31`, lines 33–48):
  ```python
  EXCLUDE_DIRS = {
      ".git",
      ".pytest_cache",
      ".antigravity",
      "node_modules",
      "__pycache__",
      ".venv",
      "venv",
      "build",
      "build_ninja",
      "CMakeFiles",
      "x64",
      "Debug",
      "Release",
  }
  ```
  *Key Observation*: `.antigravity`, `.git`, `.pytest_cache`, and `node_modules` were explicitly listed, but `.agents` was missing from the committed set.
- **Current Working Tree State**:
  An unstaged modification exists in `tools/lint/check_code_and_doc_hygiene.py` (timestamp 2026-10-01 09:15:50) where `".agents"` was inserted into `EXCLUDE_DIRS` at line 37:
  ```diff
  diff --git a/tools/lint/check_code_and_doc_hygiene.py b/tools/lint/check_code_and_doc_hygiene.py
  index f4f343c..8427d4e 100644
  --- a/tools/lint/check_code_and_doc_hygiene.py
  +++ b/tools/lint/check_code_and_doc_hygiene.py
  @@ -34,6 +34,7 @@ EXCLUDE_DIRS = {
       ".git",
       ".pytest_cache",
       ".antigravity",
  +    ".agents",
       "node_modules",
       "__pycache__",
       ".venv",
  ```

### 1.3. Quantitative Scan Telemetry (With vs Without `.agents`)
Empirical audit comparison executed on workspace:
- **WITH `.agents` scanned**:
  - Total files scanned: **1,053** (Code: 439, Docs: 614)
  - Hard Cap Errors: **1** (`.agents\teamwork\reviewer_m1_2\adversarial_tests.py` - 594 lines)
  - Soft Cap Warnings in `.agents`: **5** (1 code file > 350 lines, 4 handoff/report docs > 400 lines)
  - Result under `--strict`: **EXIT CODE 1 (FAIL)**
- **WITHOUT `.agents` scanned** (`.agents` in `EXCLUDE_DIRS`):
  - Total files scanned: **514** (Code: 393, Docs: 121)
  - Hard Cap Errors: **0**
  - Hard Cap Warnings in production code: 30 warnings (all <= 500 lines soft cap warnings)
  - Result under `--strict`: **EXIT CODE 0 (PASS)**
- **Net Delta**: 539 files (51.2% of all traversed files) belong purely to the `.agents/` swarm workspace.

### 1.4. Inventory of Rogue Files in `.agents/teamwork/`
Total files in `.agents/teamwork/`: **553 files**
- Standard Metadata files:
  - `.md` (reports, handoffs, briefings, plans, progress): 490 files
  - `.patch` / `.diff` (machine-applicable changes): 9 files
- **Rogue / Non-Metadata Code Files**: **46 files**
  - 38 `.py` files
  - 8 `.js` files
  - 2 `.css` files
  - 2 `.html` files
  - 4 `.pyc` files (compiled bytecode in `__pycache__`)

Breakdown of non-metadata files by category:
1. **Rogue Standalone Test Suite**:
   - `.agents/teamwork/reviewer_m1_2/adversarial_tests.py`: **594 lines**, 26,589 bytes. Contains 14 `unittest.IsolatedAsyncioTestCase` tests for Chat policies, moderation, HMAC links, and 64-shard routing. All 14 tests pass (0.17s unittest / 0.34s pytest).
2. **Replacement Code Proposals (`proposed_*`)**:
   - `explorer_m1_1_gen2/proposed_hud_orbs.js`, `proposed_hud_skills.css`, `proposed_index_markup.html`, `proposed_test_hud_orbs.py`
   - `explorer_m1_2_gen2/proposed_hud_skills.css`, `proposed_index_patch.html`, `proposed_skill_bar_controller.js`, `proposed_test_suite.py`
   - `explorer_m1_fix_2/proposed_skill_bar_controller.js`
   - `explorer_m1_fix_3/proposed_hud_orbs.js`, `proposed_skill_bar_controller.js`
   - `explorer_m2_1/proposed_target_dummy_telemetry.js`, `proposed_test_target_dummy_and_telemetry.py`
   - `explorer_m4_1/proposed_telegraph_renderer.js`, `proposed_test_telegraph_renderer.py`
   - `explorer_m4_1_gen2/proposed_telegraph_renderer.js`, `proposed_test_telegraph_renderer.py`
   - `explorer_m4_2_gen2/proposed_test_dodge_and_evasion_iframe.py`
3. **Scratch / Survey Scripts**:
   - `challenger_m1_progression_1/challenge_exp_curve.py` (338 lines)
   - `challenger_m1_progression_2/challenge_progression_benchmarks.py` (404 lines)
   - `explorer_m1_progression_3/scratch_test_curve.py`, `test_m1_integrity.py`, `test_m1_verification_suite.py`, `test_mono_equal.py`
   - `explorer_survey_balance_1/scratch_curve_explorer.py`, `test_sim.py`
   - `explorer_survey_i18n_1/analyze_i18n.py`, `audit_code_references.py`, `audit_descriptions.py`, `audit_details.py`, `audit_key_coverage.py`, `audit_templates.py`, `audit_vi_all.py`, `audit_vi_en.py`, `verify_test_suite_proposals.py`
   - `explorer_survey_wiki_1/audit_wiki_scan.py`, `check_links.py`
   - `reviewer_m1_progression_2/test_migration_adversarial.py`
   - `worker_m2_1/build_catalog_file.py`, `check_desc_periods.py`, `check_microcopy.py`, `dump_keys.py`, `generate_catalog.py` (220 lines), `generate_dict_catalog.py`, `test_emoji.py`, `test_parse.py`, `test_parse2.py`
4. **Bytecode Artifacts**:
   - `explorer_m1_progression_3/__pycache__/*.pyc` (2 files)
   - `explorer_survey_balance_1/__pycache__/*.pyc` (1 file)
   - `worker_m2_1/__pycache__/*.pyc` (1 file)

---

## 2. Logic Chain

1. **Premise 1**: FreeExile's Teamwork architectural layout convention explicitly states:
   > "`.agents/teamwork/` must contain only metadata (plans, progress, handoffs) — source, tests, or data there is a violation." (Referenced in system instructions and PROJECT.md layout compliance).
2. **Premise 2**: FreeExile's quality gate requires `python tools/lint/check_code_and_doc_hygiene.py --strict` to pass with exit code 0 (`ORIGINAL_REQUEST.md` line 311).
3. **Observation Link A**: In commit `3be7f31`, `tools/lint/check_code_and_doc_hygiene.py` defined `EXCLUDE_DIRS = {".git", ".pytest_cache", ".antigravity", "node_modules", "__pycache__", ...}` but omitted `".agents"`.
4. **Observation Link B**: Subagent `reviewer_m1_2` placed an adversarial test suite (`adversarial_tests.py`, 594 lines) directly in `.agents/teamwork/reviewer_m1_2/`.
5. **Deduction 1**: Because `.agents` was not in `EXCLUDE_DIRS`, `check_code_and_doc_hygiene.py`'s `os.walk` recursed into `.agents/teamwork/` and evaluated all code and markdown files therein against production code caps.
6. **Deduction 2**: `adversarial_tests.py` has 594 lines, which exceeds `CODE_HARD_CAP` (500 lines). The auditor classified this as an `ERROR`, setting `is_compliant = False` and causing `--strict` mode to exit with code 1.
7. **Deduction 3**: Even if `adversarial_tests.py` were deleted, scanning `.agents/` remains an existential liability for the CI gate:
   - Any agent handoff report exceeding 600 lines (`DOC_HARD_CAP`) causes exit code 1.
   - Any proposed replacement file (`proposed_<filename>`) exceeding 500 lines causes exit code 1.
   - Any agent scratch script function exceeding 50 lines emits false-positive warnings.
   - The scanner wastes cycles reading 539 non-production metadata files.
8. **Deduction 4**: Conversely, simply adding `".agents"` to `EXCLUDE_DIRS` without cleaning rogue files leaves the `.agents/teamwork/` directory in violation of the metadata-only rule.
9. **Synthesis**: The resolution requires a unified two-step remedy: (1) permanently commit `".agents"` in `EXCLUDE_DIRS`, and (2) clean or migrate rogue test/bytecode files from `.agents/teamwork/`.

---

## 3. Caveats

1. **Unstaged Working Copy State**: The file `tools/lint/check_code_and_doc_hygiene.py` already has `".agents"` added to `EXCLUDE_DIRS` in the working tree, but this change is UNSTAGED and UNCOMMITTED. Running `git restore` would revert it to the failing state.
2. **Value of the Rogue Test Suite**: The 14 tests in `reviewer_m1_2/adversarial_tests.py` are mathematically sound and verify critical edge cases (Unicode homoglyphs, 64-shard routing, HMAC tampering). They are NOT currently present verbatim in `tests/security_fuzzing/test_chat_concurrency_and_routing_adversarial.py` or `tests/security_fuzzing/test_chat_moderation_adversarial.py`. If deleted outright, this test coverage would be lost. However, if moved into `tests/` without modular splitting, the 594-line file would fail the hygiene gate inside `tests/`! Therefore, any migration into `tests/security_fuzzing/` must split the file into two units <= 350-500 lines (e.g. `test_chat_policies_adversarial.py` and `test_chat_routing_adversarial.py`).
3. **Proposed Replacement Files (`proposed_*`)**: These are historical artifacts generated by earlier subagents communicating proposals per teamwork guidelines. Because `.agents` should be excluded, these files do not threaten the build gate once `EXCLUDE_DIRS` includes `.agents`.

---

## 4. Conclusion

The root cause of the hygiene audit failure is a **dual flaw**:
1. **Linter Vulnerability**: `tools/lint/check_code_and_doc_hygiene.py` omitted `.agents` from `EXCLUDE_DIRS`, erroneously treating internal multi-agent workspace files as production codebase files.
2. **Framework Convention Breach**: `reviewer_m1_2` created a 594-line test file (`adversarial_tests.py`) directly inside `.agents/teamwork/reviewer_m1_2/`, breaching the rule that `.agents/teamwork/` must contain only metadata.

### Recommended Precise Fix Strategy

#### Phase 1: Permanent Linter Protection (Mandatory & Immediate)
Ensure `tools/lint/check_code_and_doc_hygiene.py` has `".agents"` in `EXCLUDE_DIRS`:
```python
EXCLUDE_DIRS = {
    ".git",
    ".pytest_cache",
    ".antigravity",
    ".agents",          # <-- Exclude multi-agent teamwork workspace
    "node_modules",
    "__pycache__",
    ".venv",
    "venv",
    "build",
    "build_ninja",
    "CMakeFiles",
    "x64",
    "Debug",
    "Release",
}
```
*Rationale*: This guarantees that agent scratchpads, long reports, and proposed patches can never trigger false-positive quality gate failures or double the audit scan time.

#### Phase 2: Workspace Sanitization & Test Preservation (Recommended)
1. **Preserve Valuable Tests**: If the team wishes to retain the 14 adversarial tests from `reviewer_m1_2/adversarial_tests.py`:
   - Split `adversarial_tests.py` into two modular test suites inside `tests/security_fuzzing/`:
     - `tests/security_fuzzing/test_chat_channel_policies_adversarial.py` (~280 lines): `AdversarialChannelPoliciesTest` and `AdversarialItemLinkTest`.
     - `tests/security_fuzzing/test_chat_router_and_sharding_adversarial.py` (~310 lines): `AdversarialClusterRouterTest` and `AdversarialModerationTest`.
   - Both files comply with `CODE_SOFT_CAP <= 350` and `CODE_HARD_CAP <= 500`.
2. **Remove Rogue File**: Delete `.agents/teamwork/reviewer_m1_2/adversarial_tests.py`.
3. **Purge Bytecode Artifacts**: Delete all `__pycache__` directories inside `.agents/teamwork/` (`find_by_name` identified 4 `.pyc` files).

---

## 5. Verification Method

To independently verify this investigation and the recommended fix:

1. **Verify Linter Exclusion**:
   Run:
   ```bash
   python -c "import sys; sys.path.insert(0, 'tools/lint'); import check_code_and_doc_hygiene as h; assert '.agents' in h.EXCLUDE_DIRS, 'Missing .agents in EXCLUDE_DIRS'; print('CONFIRMED: .agents is in EXCLUDE_DIRS')"
   ```
2. **Execute Full Hygiene Audit**:
   Run:
   ```bash
   python tools/lint/check_code_and_doc_hygiene.py --strict
   ```
   *Expected Output*: Exit code `0`, `0 FILE VI PHẠM HARD CAP (ERROR)`, and `Tổng số file đã quét: ~514` (proving all 539 files in `.agents` are completely skipped).
3. **Simulate Invalidation Condition (Reproduce Failure)**:
   Run:
   ```bash
   python -c "import sys; sys.path.insert(0, 'tools/lint'); import check_code_and_doc_hygiene as h; h.EXCLUDE_DIRS.discard('.agents'); rep = h.run_hygiene_audit('c:/Projects/FreeExile'); errs = [v for v in rep.file_violations if v.severity == 'ERROR']; print(f'Reproduced {len(errs)} errors: {[e.file_path for e in errs]}')"
   ```
   *Expected Output*: Exactly 1 error pointing to `.agents\teamwork\reviewer_m1_2\adversarial_tests.py (594 dòng)`.
4. **Verify Test Suite Integrity**:
   Run:
   ```bash
   pytest .agents/teamwork/reviewer_m1_2/adversarial_tests.py -v
   ```
   *Expected Output*: `14 passed in ~0.34s`.
