ai-engineering-loop 1.0.14 → 1.0.15

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 (33) hide show
  1. package/.agents/workflows/ai-engineering-loop.md +1 -1
  2. package/.claude/skills/ai-engineering-loop/SKILL.md +1 -1
  3. package/.gemini/skills/ai-engineering-loop/SKILL.md +1 -1
  4. package/.grok/skills/ai-engineering-loop/SKILL.md +1 -1
  5. package/README.md +3 -3
  6. package/adapters/dot/README.md +8 -8
  7. package/adapters/dot/coreview.md +3 -2
  8. package/adapters/dot/gitlab.md +3 -3
  9. package/adapters/dot/mattermost.md +59 -71
  10. package/adapters/dot/multi-branch.md +3 -2
  11. package/adapters/dot/skills/dot-dev-workflow/SKILL.md +2 -2
  12. package/adapters/dot/skills/task-impact-inquiry/SKILL.md +155 -0
  13. package/bin/ai-engineering-loop.js +2 -2
  14. package/core/grill-policy.md +14 -10
  15. package/examples/backend-api/payment-idempotency/README.md +3 -3
  16. package/examples/dot/status-display/README.md +23 -0
  17. package/examples/dot/status-display/delivery-report.md +41 -0
  18. package/examples/dot/status-display/goal-contract.md +46 -0
  19. package/examples/dot/status-display/judge-verdict.md +44 -0
  20. package/examples/dot/status-display/review-findings.md +63 -0
  21. package/examples/initialization/README.md +2 -2
  22. package/examples/initialization/discovery-trace.md +1 -1
  23. package/examples/mobile-app/offline-sync-queue/README.md +3 -3
  24. package/lib/sync-hosts.js +4 -1
  25. package/package.json +1 -1
  26. package/tests/no-company-leak.test.js +82 -0
  27. package/tests/skill-host-compat.test.js +24 -7
  28. package/tests/sync-hosts.test.js +19 -1
  29. package/examples/dot/attendance-confirmation/README.md +0 -22
  30. package/examples/dot/attendance-confirmation/delivery-report.md +0 -51
  31. package/examples/dot/attendance-confirmation/goal-contract.md +0 -39
  32. package/examples/dot/attendance-confirmation/judge-verdict.md +0 -43
  33. package/examples/dot/attendance-confirmation/review-findings.md +0 -57
@@ -22,12 +22,12 @@ Task: Implement atomic idempotency key validation and SELECT FOR UPDATE row lock
22
22
 
23
23
  ## 3. Walkthrough Artifacts
24
24
 
25
- 1. **[Goal Contract (`goal-contract.md`)](file:///Users/egagofur/Development/work/ai-engineering-loop/examples/backend-api/payment-idempotency/goal-contract.md)**:
25
+ 1. **[Goal Contract (`goal-contract.md`)](./goal-contract.md)**:
26
26
  - AC-1: Idempotency-Key header mandatory on POST `/api/v1/payments/charge`.
27
27
  - AC-2: Atomic reservation using PostgreSQL `INSERT ... ON CONFLICT DO NOTHING`.
28
28
  - AC-3: Concurrent requests for same user wallet serialized with `SELECT ... FOR UPDATE`.
29
- 2. **[Adversarial Review Findings (`review-findings.md`)](file:///Users/egagofur/Development/work/ai-engineering-loop/examples/backend-api/payment-idempotency/review-findings.md)**:
29
+ 2. **[Adversarial Review Findings (`review-findings.md`)](./review-findings.md)**:
30
30
  - Devil's Advocate activates `backend-api` rules (concurrency, database atomicity).
31
31
  - Flags missing rollback on external gateway timeout (`ERR-001`).
32
- 3. **[Judge Verdict (`judge-verdict.md`)](file:///Users/egagofur/Development/work/ai-engineering-loop/examples/backend-api/payment-idempotency/judge-verdict.md)**:
32
+ 3. **[Judge Verdict (`judge-verdict.md`)](./judge-verdict.md)**:
33
33
  - Evaluates parallel test execution (`go test -race ./...`), verifies concurrency safety, and issues `PASS` verdict.
@@ -0,0 +1,23 @@
1
+ # Reference Example: Request Display Status Fix
2
+
3
+ ## 1. Context & Scenario
4
+
5
+ This walkthrough shows how a status-display bug moves through the **AI Engineering Loop** and the **DOT Delivery Adapter**. Names, URLs, and schema below are **fictional**. Do not copy real client tickets, GitLab links, or field names into this package.
6
+
7
+ ### The Problem
8
+
9
+ On an employee portal, request cards on the list and pagination endpoints showed `"PENDING"` after every line item was already approved or rejected. Non-standard-window records were also scored with the standard-day rule.
10
+
11
+ ---
12
+
13
+ ## 2. Walkthrough Stages & Artifacts
14
+
15
+ 1. **[Stage 1: Goal Contract (`goal-contract.md`)](./goal-contract.md)**:
16
+ - Objective, acceptance criteria (standard window, holiday, non-standard window, null values), and verification plan.
17
+ 2. **[Stage 2: Adversarial Review & Triage (`review-findings.md`)](./review-findings.md)**:
18
+ - Devil's Advocate flags a null-safety bug (`COR-001`) and an invalid nitpick (`MAINT-001`).
19
+ - Maker triage and surgical fix.
20
+ 3. **[Stage 3: Judge Evaluation & Verdict (`judge-verdict.md`)](./judge-verdict.md)**:
21
+ - Audit of tests, typecheck, finding resolutions, and `PASS`.
22
+ 4. **[Stage 4: DOT Delivery Pipeline (`delivery-report.md`)](./delivery-report.md)**:
23
+ - Fictional issue, base MR, cherry-picks to `staging` and `develop`, Coreview triage, Mattermost notice.
@@ -0,0 +1,41 @@
1
+ # DOT Delivery Report: Request Display Status Fix
2
+
3
+ Fictional sample. Replace host, group, repo, issue, and MR ids from `glab` output. Never paste real client URLs into this package.
4
+
5
+ ## 1. Summary of Delivery Actions
6
+
7
+ 1. **GitLab Issue Created**: [Issue #42 - [BE] [Requests] Fix display status](https://gitlab.example.com/example-org/work-portal/-/issues/42).
8
+ 2. **Primary MR Created**: [MR !10 targeting `main`](https://gitlab.example.com/example-org/work-portal/-/merge_requests/10).
9
+ 3. **Multi-Branch Cherry-Pick**:
10
+ - [MR !11 targeting `staging`](https://gitlab.example.com/example-org/work-portal/-/merge_requests/11).
11
+ - [MR !12 targeting `develop`](https://gitlab.example.com/example-org/work-portal/-/merge_requests/12).
12
+ 4. **Coreview Bot Triage**:
13
+ - Comments fetched on MR !12. Zero blocking comments.
14
+ 5. **Mattermost Notification**:
15
+ - Resolved repository `example-org/work-portal` to channel `"team-work-portal"`.
16
+ - Dispatched via MCP `mattermost_send_message` with `from: "AI Agent"`.
17
+
18
+ ---
19
+
20
+ ## 2. GitLab Links
21
+
22
+ | Artifact | Branch | Link |
23
+ |---|---|---|
24
+ | **GitLab Issue** | — | [Issue #42](https://gitlab.example.com/example-org/work-portal/-/issues/42) |
25
+ | **Merge Request DEV** | `develop` | [MR !12](https://gitlab.example.com/example-org/work-portal/-/merge_requests/12) |
26
+ | **Merge Request STAGING** | `staging` | [MR !11](https://gitlab.example.com/example-org/work-portal/-/merge_requests/11) |
27
+ | **Merge Request MAIN** | `main` | [MR !10](https://gitlab.example.com/example-org/work-portal/-/merge_requests/10) |
28
+
29
+ ---
30
+
31
+ ## 3. Dispatched Mattermost Notification
32
+
33
+ ```text
34
+ [MR DEV] https://gitlab.example.com/example-org/work-portal/-/merge_requests/12
35
+ Changes log
36
+ - Include standard-window and rush-note fields when loading request list pages.
37
+ - Resolve display status from all line items, including holiday and null collections.
38
+ - Add unit tests for standard, holiday, non-standard-window, and null line-item cases.
39
+
40
+ cc: @owner
41
+ ```
@@ -0,0 +1,46 @@
1
+ # Goal Contract: Request Display Status Fix
2
+
3
+ ## 1. Objective
4
+
5
+ Fix incorrect display status on list and pagination endpoints when a request has mixed line items, holiday logs, non-standard windows, or null collections.
6
+
7
+ ## 2. Business Outcome & User Lifecycle Impact
8
+
9
+ - **Employees**: See APPROVED, REJECTED, or NEED_APPROVAL matching the real record.
10
+ - **Reviewers**: Stop getting false pending notices for already-settled holiday logs.
11
+ - **Finance**: Totals used by the downstream aggregate job stay consistent.
12
+
13
+ ## 3. Acceptance Criteria (AC)
14
+
15
+ - [ ] **AC-1**: If `hasStandardWindow = true` and `duration` is within the standard day limit on a weekday without a rush note, display status is `APPROVED` or `NEED_APPROVAL` from clock-in/out presence only.
16
+ - [ ] **AC-2**: If a rush note exists, or duration exceeds the standard limit, or `isHoliday = true`, evaluate pending status across all associated `lineItems`.
17
+ - [ ] **AC-3**: Non-standard-window records (`user.type.hasStandardWindow = false`) must not use the weekday duration threshold.
18
+ - [ ] **AC-4**: Null or missing `lineItems` default to `APPROVED` without throwing `TypeError`.
19
+ - [ ] **AC-5**: The existing API response contract is unchanged.
20
+
21
+ ## 4. Technical Constraints
22
+
23
+ - Keep the existing list/pagination query shape.
24
+ - Centralize logic in a pure function: `resolveRequestDisplayStatus`.
25
+ - No new runtime dependencies.
26
+ - `tsc --noEmit` exits 0.
27
+
28
+ ## 5. Out of Scope
29
+
30
+ - Frontend layout changes.
31
+ - Database migrations.
32
+ - Changing the downstream aggregate/export job.
33
+
34
+ ## 6. Verification Requirements
35
+
36
+ - **Unit Tests**: Jest suite at `src/server/requests/utils/resolve-display-status.test.ts`.
37
+ - **Typecheck**: `npx tsc --noEmit` exits 0.
38
+ - **Linter**: `npx eslint --fix` on modified files, 0 errors.
39
+ - **Regression**: commands in `.ai-engineering-loop/verification.md` (example: `npx jest && npx tsc --noEmit`).
40
+
41
+ ## 7. Definition of Done (DoD)
42
+
43
+ - [ ] AC-1 through AC-5 proven by unit tests.
44
+ - [ ] Deterministic verification passes.
45
+ - [ ] Devil's Advocate review with 0 unresolved blocking findings.
46
+ - [ ] Judge issues PASS.
@@ -0,0 +1,44 @@
1
+ # Judge Evaluation Report: Request Display Status Fix
2
+
3
+ ## 1. Executive Verdict
4
+
5
+ - **Verdict**: `PASS`
6
+ - **Iteration**: `Iteration 2 of 3`
7
+ - **Confidence**: `HIGH`
8
+
9
+ ---
10
+
11
+ ## 2. Deterministic Verification Audit
12
+
13
+ | Check | Command Executed | Raw Result | Status |
14
+ |---|---|---|:---:|
15
+ | **Unit Tests** | `npx jest src/server/requests/utils/resolve-display-status.test.ts` | `Tests: 12 passed, 12 total.` | PASS |
16
+ | **Full Suite** | `npx jest && npx tsc --noEmit` | `Test Suites: 12 passed. tsc exit 0.` | PASS |
17
+ | **TypeScript** | `npx tsc --noEmit` | `Exit code 0.` | PASS |
18
+ | **Linter** | `npx eslint --fix src/server/requests/**` | `0 errors.` | PASS |
19
+
20
+ ---
21
+
22
+ ## 3. Goal Contract Compliance Audit
23
+
24
+ | Criterion | Verified By Test / Artifact | Result |
25
+ |---|---|:---:|
26
+ | **AC-1**: Standard-window weekday | `resolve-display-status.test.ts > standard window` | PASS |
27
+ | **AC-2**: Holiday and over-limit handling | `resolve-display-status.test.ts > holiday rush` | PASS |
28
+ | **AC-3**: Non-standard-window records | `resolve-display-status.test.ts > non-standard window` | PASS |
29
+ | **AC-4**: Null `lineItems` | `resolve-display-status.test.ts > null safety` | PASS |
30
+ | **AC-5**: API contract | router typecheck | PASS |
31
+
32
+ ---
33
+
34
+ ## 4. Finding Triage Audit
35
+
36
+ - **COR-001 (High - Null Safety)**: Maker applied null coalescing in Iteration 2. **Status: RESOLVED & VERIFIED**.
37
+ - **MAINT-001 (Low - Factory Suggestion)**: Invalid speculative nitpick. **Status: DISMISSED / INVALID**.
38
+
39
+ ---
40
+
41
+ ## 5. Formal Conclusion & Hand-off
42
+
43
+ Definition of Done is met with reproducible evidence.
44
+ **Authorized next action**: DOT Delivery Adapter (`adapters/dot/README.md`) for GitLab MR, multi-branch cherry-pick, Coreview triage, and Mattermost.
@@ -0,0 +1,63 @@
1
+ # Adversarial Review Findings & Triage: Request Display Status Fix
2
+
3
+ ## 1. Review Summary
4
+
5
+ - **Reviewer**: Devil's Advocate Agent
6
+ - **Target Branch**: `main...fix/request-display-status`
7
+ - **Total Findings**: 2
8
+ - **Blocking (SEV-1/2)**: 1
9
+ - **Non-Blocking / Invalid**: 1
10
+
11
+ ---
12
+
13
+ ## 2. Findings Ledger
14
+
15
+ ### Finding COR-001: Missing null safety when iterating `lineItems`
16
+
17
+ - **Severity**: `HIGH` (SEV-2)
18
+ - **Category**: `Correctness`
19
+ - **Location**: `src/server/requests/utils/resolve-display-status.ts:34-41`
20
+ - **Evidence**:
21
+
22
+ ```typescript
23
+ const hasPending = confirmation.lineItems.some(
24
+ (item) => item.status === "NEED_APPROVAL"
25
+ );
26
+ ```
27
+
28
+ - **Problem**:
29
+ If `confirmation.lineItems` is `null` or `undefined` (legacy rows), `.some()` throws `TypeError`.
30
+ - **Impact**:
31
+ Pagination API crashes for historical records.
32
+ - **Recommendation**:
33
+
34
+ ```diff
35
+ - const hasPending = confirmation.lineItems.some(
36
+ + const hasPending = (confirmation.lineItems ?? []).some(
37
+ (item) => item.status === "NEED_APPROVAL"
38
+ );
39
+ ```
40
+
41
+ - **Confidence**: `HIGH`
42
+ - **Status**: `TRIAGED_VALID`
43
+ - **Resolution**:
44
+ Maker applied `(confirmation.lineItems ?? [])` and added `should return APPROVED when lineItems is null or undefined`.
45
+
46
+ ---
47
+
48
+ ### Finding MAINT-001: Suggestion to convert helper into an abstract factory class
49
+
50
+ - **Severity**: `LOW` (SEV-4)
51
+ - **Category**: `Maintainability`
52
+ - **Location**: `src/server/requests/utils/resolve-display-status.ts:1-50`
53
+ - **Evidence**:
54
+ Utility is `export function resolveRequestDisplayStatus(...)`.
55
+ - **Problem**:
56
+ Reviewer wanted a Strategy/Factory for future calculator swaps.
57
+ - **Impact**:
58
+ None. Pure functions match this repo.
59
+ - **Recommendation**: Refactor to `class StatusCalculatorFactory`.
60
+ - **Confidence**: `LOW`
61
+ - **Status**: `TRIAGED_INVALID`
62
+ - **Triage Reason**:
63
+ Speculative overengineering. Constraint: surgical change, no extra abstractions.
@@ -13,7 +13,7 @@ This walkthrough demonstrates how the **AI Engineering Loop** automatically init
13
13
 
14
14
  ## 2. Walkthrough Artifacts
15
15
 
16
- 1. **[Discovery Execution Trace (`discovery-trace.md`)](file:///Users/egagofur/Development/work/ai-engineering-loop/examples/initialization/discovery-trace.md)**:
16
+ 1. **[Discovery Execution Trace (`discovery-trace.md`)](./discovery-trace.md)**:
17
17
  - Full 5-pass log of directory inspection, manifest parsing, script discovery, architecture tracing, and second-pass quality check.
18
- 2. **[Generated Context Artifacts (`generated-context.md`)](file:///Users/egagofur/Development/work/ai-engineering-loop/examples/initialization/generated-context.md)**:
18
+ 2. **[Generated Context Artifacts (`generated-context.md`)](./generated-context.md)**:
19
19
  - The exact evidence-based `.ai-engineering-loop/` files generated automatically by the agent without user intervention.
@@ -18,7 +18,7 @@
18
18
  - `packages/` (contains `ui/`, `database/`, `shared/`)
19
19
  - `pnpm-workspace.yaml` (detected `pnpm` monorepo)
20
20
  - `turbo.json` (detected Turborepo pipeline)
21
- - **Profile Binding**: Bound [`profiles/monorepo.md`](file:///Users/egagofur/Development/work/ai-engineering-loop/profiles/monorepo.md).
21
+ - **Profile Binding**: Bound [`profiles/monorepo.md`](../../profiles/monorepo.md).
22
22
 
23
23
  ### Pass 2: Manifests & Verification Commands Discovery
24
24
  - Parsed `package.json` (root):
@@ -22,12 +22,12 @@ Task: Implement persistent offline SQLite mutation queue with exponential backof
22
22
 
23
23
  ## 3. Walkthrough Artifacts
24
24
 
25
- 1. **[Goal Contract (`goal-contract.md`)](file:///Users/egagofur/Development/work/ai-engineering-loop/examples/mobile-app/offline-sync-queue/goal-contract.md)**:
25
+ 1. **[Goal Contract (`goal-contract.md`)](./goal-contract.md)**:
26
26
  - AC-1: All form submissions persist immediately to local SQLite `mutation_queue` table before network dispatch.
27
27
  - AC-2: Background sync engine triggers on network restoration with exponential backoff.
28
28
  - AC-3: OS suspension / app kill must not drop un-synced items.
29
- 2. **[Adversarial Review Findings (`review-findings.md`)](file:///Users/egagofur/Development/work/ai-engineering-loop/examples/mobile-app/offline-sync-queue/review-findings.md)**:
29
+ 2. **[Adversarial Review Findings (`review-findings.md`)](./review-findings.md)**:
30
30
  - Devil's Advocate activates `mobile-app` rules (offline persistence, lifecycle, battery).
31
31
  - Flags missing disk write error handling when device storage is full (`PERF-001`).
32
- 3. **[Judge Verdict (`judge-verdict.md`)](file:///Users/egagofur/Development/work/ai-engineering-loop/examples/mobile-app/offline-sync-queue/judge-verdict.md)**:
32
+ 3. **[Judge Verdict (`judge-verdict.md`)](./judge-verdict.md)**:
33
33
  - Audits Flutter unit & mock network tests, verifies 100% pass, and issues `PASS` verdict.
package/lib/sync-hosts.js CHANGED
@@ -33,6 +33,7 @@ function hostFileMap(home) {
33
33
  root: claude,
34
34
  files: [
35
35
  { src: '.claude/skills/ai-engineering-loop/SKILL.md', dest: path.join(claude, 'skills/ai-engineering-loop/SKILL.md'), mode: 'upsert' },
36
+ { src: 'adapters/dot/skills/task-impact-inquiry/SKILL.md', dest: path.join(claude, 'skills/task-impact-inquiry/SKILL.md'), mode: 'upsert' },
36
37
  { src: '.claude/agents/devil-advocate.md', dest: path.join(claude, 'agents/devil-advocate.md'), mode: 'upsert' },
37
38
  { src: '.claude/agents/judge.md', dest: path.join(claude, 'agents/judge.md'), mode: 'upsert' },
38
39
  { src: '.claude/commands/ai-engineering-loop.md', dest: path.join(claude, 'commands/ai-engineering-loop.md'), mode: 'upsert' }
@@ -43,6 +44,7 @@ function hostFileMap(home) {
43
44
  root: grok,
44
45
  files: [
45
46
  { src: '.grok/skills/ai-engineering-loop/SKILL.md', dest: path.join(grok, 'skills/ai-engineering-loop/SKILL.md'), mode: 'upsert', grokSkillOverlay: true },
47
+ { src: 'adapters/dot/skills/task-impact-inquiry/SKILL.md', dest: path.join(grok, 'skills/task-impact-inquiry/SKILL.md'), mode: 'upsert', grokSkillOverlay: true },
46
48
  { src: '.grok/agents/devil-advocate.md', dest: path.join(grok, 'agents/devil-advocate.md'), mode: 'upsert' },
47
49
  { src: '.grok/agents/judge.md', dest: path.join(grok, 'agents/judge.md'), mode: 'upsert' },
48
50
  { src: '.grok/commands/ai-engineering-loop.md', dest: path.join(grok, 'commands/ai-engineering-loop.md'), mode: 'upsert' }
@@ -52,7 +54,8 @@ function hostFileMap(home) {
52
54
  id: 'gemini',
53
55
  root: gemini,
54
56
  files: [
55
- { src: '.gemini/skills/ai-engineering-loop/SKILL.md', dest: path.join(gemini, 'config/skills/ai-engineering-loop/SKILL.md'), mode: 'upsert' }
57
+ { src: '.gemini/skills/ai-engineering-loop/SKILL.md', dest: path.join(gemini, 'config/skills/ai-engineering-loop/SKILL.md'), mode: 'upsert' },
58
+ { src: 'adapters/dot/skills/task-impact-inquiry/SKILL.md', dest: path.join(gemini, 'config/skills/task-impact-inquiry/SKILL.md'), mode: 'upsert' }
56
59
  ]
57
60
  },
58
61
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-engineering-loop",
3
- "version": "1.0.14",
3
+ "version": "1.0.15",
4
4
  "description": "A reusable, framework-agnostic AI Engineering Operating System for autonomous coding agents.",
5
5
  "main": "bin/ai-engineering-loop.js",
6
6
  "bin": {
@@ -0,0 +1,82 @@
1
+ 'use strict';
2
+
3
+ const test = require('node:test');
4
+ const assert = require('node:assert');
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+
8
+ const ROOT = path.join(__dirname, '..');
9
+
10
+ const SKIP_DIR = new Set([
11
+ '.git',
12
+ 'node_modules',
13
+ '.serena',
14
+ '.DS_Store'
15
+ ]);
16
+
17
+ function walk(dir, out = []) {
18
+ for (const name of fs.readdirSync(dir)) {
19
+ if (SKIP_DIR.has(name)) continue;
20
+ const abs = path.join(dir, name);
21
+ const st = fs.lstatSync(abs);
22
+ if (st.isSymbolicLink()) continue;
23
+ if (st.isDirectory()) walk(abs, out);
24
+ else if (st.isFile()) out.push(abs);
25
+ }
26
+ return out;
27
+ }
28
+
29
+ function rel(abs) {
30
+ return path.relative(ROOT, abs).split(path.sep).join('/');
31
+ }
32
+
33
+ const FINGERPRINTS = [
34
+ { re: /dotify/i, label: 'dotify' },
35
+ { re: /bikin-rindu/i, label: 'bikin-rindu' },
36
+ { re: /hasNormalHours/, label: 'hasNormalHours' },
37
+ { re: /overtimeNote/, label: 'overtimeNote' },
38
+ { re: /attendanceConfirmation/i, label: 'attendanceConfirmation' },
39
+ { re: /internal-dotify/, label: 'internal-dotify' },
40
+ { re: /hanaaaca/, label: 'coworker handle' },
41
+ { re: /ulfa\.mufida/, label: 'coworker handle' },
42
+ { re: /kontribusi\/mattermost-agent/, label: 'local mattermost-agent checkout' },
43
+ { re: /dot-system\//, label: 'dot-system/' },
44
+ { re: /timeEntities/, label: 'timeEntities' },
45
+ { re: /resolveAttendanceConfirmation/, label: 'resolveAttendanceConfirmation' },
46
+ { re: /attendance-confirmations/, label: 'attendance-confirmations' }
47
+ ];
48
+
49
+ test('packaged files do not embed real client tickets, schema, or machine paths', () => {
50
+ const files = walk(ROOT).filter((abs) => {
51
+ const r = rel(abs);
52
+ return !r.startsWith('tests/no-company-leak.test.js');
53
+ });
54
+ const hits = [];
55
+ for (const abs of files) {
56
+ const r = rel(abs);
57
+ let text;
58
+ try {
59
+ text = fs.readFileSync(abs, 'utf8');
60
+ } catch {
61
+ continue;
62
+ }
63
+ if (text.includes('\u0000')) continue;
64
+
65
+ if (r !== 'bin/ai-engineering-loop.js' && /gitlab\.dot\.co\.id/.test(text)) {
66
+ hits.push(`${r}: gitlab.dot.co.id (allowed only as adapter auto-detect in bin/)`);
67
+ }
68
+ if (r === 'bin/ai-engineering-loop.js' && /gitlab\.dot\.co\.id\/.+/.test(text)) {
69
+ hits.push(`${r}: gitlab.dot.co.id with a path (ticket URL)`);
70
+ }
71
+
72
+ const inSensitiveTree = r.startsWith('adapters/') || r.startsWith('examples/');
73
+ if (inSensitiveTree && /\/Users\/egagofur/.test(text)) {
74
+ hits.push(`${r}: /Users/egagofur`);
75
+ }
76
+
77
+ for (const { re, label } of FINGERPRINTS) {
78
+ if (re.test(text)) hits.push(`${r}: ${label}`);
79
+ }
80
+ }
81
+ assert.deepStrictEqual(hits, []);
82
+ });
@@ -166,17 +166,33 @@ test('Gemini Antigravity skill matches the loop and never uses Grok spawn keys o
166
166
  assert.match(gemini, /TRUE_INDEPENDENT_AGENT/);
167
167
  });
168
168
 
169
- test('DOT adapter locates task-impact-inquiry on Antigravity Gemini skills, not Claude', () => {
169
+ test('task-impact-inquiry is Claude-safe and ships to Claude, Grok, and Gemini', () => {
170
+ const skill = readRepo('adapters/dot/skills/task-impact-inquiry/SKILL.md');
171
+ const { fm } = parseFrontmatter(skill, 'task-impact-inquiry');
172
+ assert.doesNotMatch(fm, /^description:\s*>-?/m);
173
+ assert.doesNotMatch(skill, /```mermaid/);
174
+ assert.doesNotMatch(skill, /\$\\/);
175
+ assert.doesNotMatch(skill, /spawn_subagent/);
176
+ assert.match(skill, /lifecycle/);
177
+ assert.match(skill, /ASCII/);
178
+ assert.match(skill, /failure table/);
179
+ assert.match(skill, /Do not interview again/);
180
+ assert.match(skill, /Passing unit tests are not isolation proof|Green unit tests/);
181
+ assert.match(skill, /New-dev briefing/);
182
+ assert.match(skill, /Hit map|Where it hits/);
183
+ assert.match(skill, /Do not generate an FSD/);
184
+ const grill = readRepo('core/grill-policy.md');
185
+ assert.match(grill, /Business blast radius/);
186
+ assert.match(grill, /~\/\.claude\/skills\/task-impact-inquiry/);
187
+ assert.match(grill, /~\/\.grok\/skills\/task-impact-inquiry/);
188
+ assert.match(grill, /~\/\.gemini\/config\/skills\/task-impact-inquiry/);
170
189
  const readme = readRepo('adapters/dot/README.md');
171
- assert.match(readme, /~\/\.gemini\/config\/skills/);
172
190
  assert.match(readme, /task-impact-inquiry/);
173
- assert.match(readme, /not from `~\/\.claude\/skills\/`/);
174
- assert.doesNotMatch(readme, /and `~\/\.claude\/skills\/`/);
175
- const grill = readRepo('core/grill-policy.md');
176
- assert.match(grill, /task-impact-inquiry/);
177
- assert.match(grill, /Do not skip grill/);
191
+ assert.match(readme, /~\/\.claude\/skills\//);
192
+ assert.doesNotMatch(readme, /not from `~\/\.claude\/skills\/`/);
178
193
  const wf = readRepo('.agents/workflows/ai-engineering-loop.md');
179
194
  assert.match(wf, /task-impact-inquiry/);
195
+ assert.match(wf, /blast radius: lifecycle sketch/);
180
196
  });
181
197
 
182
198
  test('DOT router sends commit-bound work to ai-engineering-loop; workflow is Stage 8 only', () => {
@@ -260,6 +276,7 @@ test('Failure table is required to freeze, TDD, verify, and Judge', () => {
260
276
  assert.match(text, /failure table/, rel);
261
277
  assert.match(text, /One red test per AC row/, rel);
262
278
  assert.match(text, /Do not freeze sunny-path-only/, rel);
279
+ assert.match(text, /blast radius: lifecycle sketch/, rel);
263
280
  }
264
281
  });
265
282
 
@@ -47,9 +47,27 @@ test('sync upserts Claude AEL files but does not invent DOT skills', () => {
47
47
  assert.ok(fs.existsSync(path.join(home, '.claude/agents/judge.md')));
48
48
  assert.ok(fs.existsSync(path.join(home, '.claude/commands/ai-engineering-loop.md')));
49
49
  assert.ok(!fs.existsSync(path.join(home, '.claude/skills/dot-dev-workflow/SKILL.md')));
50
+ assert.ok(fs.existsSync(path.join(home, '.claude/skills/task-impact-inquiry/SKILL.md')));
50
51
  assert.ok(!fs.existsSync(path.join(home, '.claude/settings.local.json')));
51
52
  });
52
53
 
54
+ test('sync upserts task-impact-inquiry onto Claude, Grok, and Gemini', () => {
55
+ const home = tmpHome();
56
+ fs.mkdirSync(path.join(home, '.claude'));
57
+ fs.mkdirSync(path.join(home, '.grok'));
58
+ fs.mkdirSync(path.join(home, '.gemini'));
59
+ applyHostSync({ packageRoot: ROOT, home });
60
+ const claude = fs.readFileSync(path.join(home, '.claude/skills/task-impact-inquiry/SKILL.md'), 'utf8');
61
+ const grok = fs.readFileSync(path.join(home, '.grok/skills/task-impact-inquiry/SKILL.md'), 'utf8');
62
+ const gemini = fs.readFileSync(path.join(home, '.gemini/config/skills/task-impact-inquiry/SKILL.md'), 'utf8');
63
+ assert.match(claude, /name: task-impact-inquiry/);
64
+ assert.doesNotMatch(claude, /```mermaid/);
65
+ assert.match(claude, /New-dev briefing/);
66
+ assert.match(grok, /^user-invocable: true$/m);
67
+ assert.match(grok, /Where it hits/);
68
+ assert.match(gemini, /Business blast radius|blast radius/);
69
+ });
70
+
53
71
  test('DOT skills update only when already installed', () => {
54
72
  const home = tmpHome();
55
73
  const dest = path.join(home, '.claude/skills/dot-dev-workflow/SKILL.md');
@@ -84,7 +102,7 @@ test('dry-run does not write; second apply is current', () => {
84
102
  assert.ok(!fs.existsSync(path.join(home, '.gemini/config/skills/ai-engineering-loop/SKILL.md')));
85
103
  applyHostSync({ packageRoot: ROOT, home });
86
104
  const again = applyHostSync({ packageRoot: ROOT, home });
87
- assert.strictEqual(summarizeHostSync(again.filter((item) => item.id === 'gemini')).current, 1);
105
+ assert.strictEqual(summarizeHostSync(again.filter((item) => item.id === 'gemini')).current, 2);
88
106
  assert.strictEqual(summarizeHostSync(again.filter((item) => item.id === 'gemini')).copy, 0);
89
107
  });
90
108
 
@@ -1,22 +0,0 @@
1
- # Reference Example: Attendance Confirmation Status Fix
2
-
3
- ## 1. Context & Scenario
4
-
5
- This reference walkthrough demonstrates how a complex real-world bug in the DOT ecosystem moves through the complete **AI Engineering Loop** and is subsequently delivered via the **DOT Delivery Adapter**.
6
-
7
- ### The Problem
8
- In the Dotify employee portal, attendance confirmation cards displayed an incorrect status (`"PENDING"`) for employees working overtime or on weekends, even when all underlying time logs had already been approved or rejected. Furthermore, non-normal hours employees (shift workers) had their records mistakenly treated under standard 9-to-5 rules.
9
-
10
- ---
11
-
12
- ## 2. Walkthrough Stages & Artifacts
13
-
14
- 1. **[Stage 1: Goal Contract (`goal-contract.md`)](file:///Users/egagofur/Development/work/ai-engineering-loop/examples/dot/attendance-confirmation/goal-contract.md)**:
15
- - Formalized objective, acceptance criteria (normal hours, weekends, non-normal hours, null values), and verification plan.
16
- 2. **[Stage 2: Adversarial Review & Triage (`review-findings.md`)](file:///Users/egagofur/Development/work/ai-engineering-loop/examples/dot/attendance-confirmation/review-findings.md)**:
17
- - Independent Devil's Advocate review flagging a timezone offset bug (`COR-001`) and an invalid nitpick (`MAINT-001`).
18
- - Maker Agent triage and surgical resolution.
19
- 3. **[Stage 3: Judge Evaluation & Verdict (`judge-verdict.md`)](file:///Users/egagofur/Development/work/ai-engineering-loop/examples/dot/attendance-confirmation/judge-verdict.md)**:
20
- - Audit of unit test results, typecheck logs, finding resolutions, and issuance of `PASS` verdict.
21
- 4. **[Stage 4: DOT Delivery Pipeline (`delivery-report.md`)](file:///Users/egagofur/Development/work/ai-engineering-loop/examples/dot/attendance-confirmation/delivery-report.md)**:
22
- - Creation of GitLab Issue #307, base MR !946, multi-branch propagation to `staging` (!947) and `develop` (!948), Coreview bot triage, and automated Mattermost channel notification.
@@ -1,51 +0,0 @@
1
- # DOT Delivery Report: Attendance Confirmation Fix
2
-
3
- ## 1. Summary of Delivery Actions
4
-
5
- Upon receiving the `PASS` verdict from the Judge Agent, the DOT Delivery Adapter executed the following release actions:
6
-
7
- 1. **GitLab Issue Created**: [Issue #307 - [BE] [Attendance] Fix Attendance Confirmation Display Status](https://gitlab.dot.co.id/dot-system/dotify-new/-/issues/307).
8
- 2. **Primary MR Created**: [MR !946 targeting `main`](https://gitlab.dot.co.id/dot-system/dotify-new/-/merge_requests/946).
9
- 3. **Multi-Branch Cherry-Pick**:
10
- - [MR !947 targeting `staging`](https://gitlab.dot.co.id/dot-system/dotify-new/-/merge_requests/947).
11
- - [MR !948 targeting `develop`](https://gitlab.dot.co.id/dot-system/dotify-new/-/merge_requests/948).
12
- 4. **Coreview Bot Triage**:
13
- - Comments fetched on MR !948. Zero blocking comments found.
14
- 5. **Mattermost Notification**:
15
- - Resolved repository `dot-system/dotify-new` to channel `"internal-dotify"`.
16
- - Dispatched Markdown report via MCP `mattermost_send_message` with `from: "AI Agent"`.
17
-
18
- ---
19
-
20
- ## 2. GitLab Links
21
-
22
- | Artifact | Branch | Link |
23
- |---|---|---|
24
- | **GitLab Issue** | — | `[Issue #307](https://gitlab.dot.co.id/dot-system/dotify-new/-/issues/307)` |
25
- | **Merge Request DEV** | `develop` | `[MR !948](https://gitlab.dot.co.id/dot-system/dotify-new/-/merge_requests/948)` |
26
- | **Merge Request STAGING** | `staging` | `[MR !947](https://gitlab.dot.co.id/dot-system/dotify-new/-/merge_requests/947)` |
27
- | **Merge Request MAIN** | `main` | `[MR !946](https://gitlab.dot.co.id/dot-system/dotify-new/-/merge_requests/946)` |
28
-
29
- ---
30
-
31
- ## 3. Dispatched Mattermost Notification
32
-
33
- ```text
34
- [MR DEV] https://gitlab.dot.co.id/dot-system/dotify-new/-/merge_requests/948
35
- Changes log
36
- - Include user.type.hasNormalHours and timeEntities.overtimeNote in attendanceConfirmationPagination Prisma query.
37
- - Create resolveAttendanceConfirmationDisplayStatus utility to properly evaluate hasPendingTimeEntities by checking overtimeNote, isWeekend, duration > 8, non-normal hours employees, and null statuses.
38
- - Add comprehensive unit tests in src/server/attendance-confirmations/utils/resolve-display-status.test.ts covering all status permutations.
39
-
40
- [MR STAGING] https://gitlab.dot.co.id/dot-system/dotify-new/-/merge_requests/947
41
- Changes log
42
- - Include user.type.hasNormalHours and timeEntities.overtimeNote in attendanceConfirmationPagination Prisma query.
43
- - Create resolveAttendanceConfirmationDisplayStatus utility to properly evaluate hasPendingTimeEntities by checking overtimeNote, isWeekend, duration > 8, non-normal hours employees, and null statuses.
44
- - Add comprehensive unit tests in src/server/attendance-confirmations/utils/resolve-display-status.test.ts covering all status permutations.
45
-
46
- [MR MAIN] https://gitlab.dot.co.id/dot-system/dotify-new/-/merge_requests/946
47
- Changes log
48
- - Include user.type.hasNormalHours and timeEntities.overtimeNote in attendanceConfirmationPagination Prisma query.
49
- - Create resolveAttendanceConfirmationDisplayStatus utility to properly evaluate hasPendingTimeEntities by checking overtimeNote, isWeekend, duration > 8, non-normal hours employees, and null statuses.
50
- - Add comprehensive unit tests in src/server/attendance-confirmations/utils/resolve-display-status.test.ts covering all status permutations.
51
- ```
@@ -1,39 +0,0 @@
1
- # Goal Contract: Attendance Confirmation Display Status Fix
2
-
3
- ## 1. Objective
4
- Fix the incorrect calculation of attendance confirmation display statuses across list and pagination endpoints when time entities contain overtime notes, weekend logs, non-normal hours employees, or null record states.
5
-
6
- ## 2. Business Outcome & User Lifecycle Impact
7
- - **Employees**: View accurate confirmation statuses (APPROVED, REJECTED, NEED_APPROVAL) reflecting their true attendance record.
8
- - **Managers / Reviewers**: Stop receiving false-positive pending approval notifications for already-settled weekend logs.
9
- - **HR & Payroll**: Accurate cumulative duration calculations for payroll export.
10
-
11
- ## 3. Acceptance Criteria (AC)
12
- - [ ] **AC-1**: If an employee has `hasNormalHours = true` and `duration <= 8` on a standard weekday without overtime notes, display status must resolve to `APPROVED` or `NEED_APPROVAL` strictly based on clock-in/out presence.
13
- - [ ] **AC-2**: If `overtimeNote` exists or `duration > 8` or `isWeekend = true`, evaluate pending status across all associated `timeEntities`.
14
- - [ ] **AC-3**: Non-normal hours employees (`user.type.hasNormalHours = false`) must not be evaluated under 8-hour weekday thresholds.
15
- - [ ] **AC-4**: Null or missing time entity collections must default safely to `APPROVED` without throwing runtime `TypeError`.
16
- - [ ] **AC-5**: Backward compatibility of the tRPC/REST response contract must be strictly preserved.
17
-
18
- ## 4. Technical Constraints
19
- - Preserve existing Prisma query schemas in `attendanceConfirmationPagination`.
20
- - Centralize logic in a pure, testable utility function: `resolveAttendanceConfirmationDisplayStatus`.
21
- - No new external runtime dependencies (use existing `dayjs` and `lodash` packages).
22
- - 0 TypeScript compiler errors on `tsc --noEmit`.
23
-
24
- ## 5. Out of Scope
25
- - Modifying the UI frontend component layouts in `dotify-new/web`.
26
- - Database schema migrations or alter table statements.
27
- - Changing payroll export report generation scripts.
28
-
29
- ## 6. Verification Requirements
30
- - **Unit Tests**: Comprehensive Jest test suite in `src/server/attendance-confirmations/utils/resolve-display-status.test.ts` covering 100% of branches.
31
- - **Typecheck**: `npx tsc --noEmit` exits with 0.
32
- - **Linter**: `npx eslint --fix` on modified files with 0 errors.
33
- - **Regression**: Run entire test suite: `npx jest --testPathIgnorePatterns="dotify-api"`.
34
-
35
- ## 7. Definition of Done (DoD)
36
- - [ ] All AC-1 through AC-5 proven by unit tests.
37
- - [ ] Deterministic verification passes 100%.
38
- - [ ] Devil's Advocate review conducted with 0 unresolved blocking findings.
39
- - [ ] Judge issues PASS verdict.
@@ -1,43 +0,0 @@
1
- # Judge Evaluation Report: Attendance Confirmation Fix
2
-
3
- ## 1. Executive Verdict
4
- - **Verdict**: `PASS`
5
- - **Iteration**: `Iteration 2 of 3`
6
- - **Confidence**: `HIGH`
7
-
8
- ---
9
-
10
- ## 2. Deterministic Verification Audit
11
-
12
- | Check | Command Executed | Raw Result | Status |
13
- |---|---|---|:---:|
14
- | **Unit Tests** | `npx jest src/server/attendance-confirmations/utils/resolve-display-status.test.ts` | `Tests: 12 passed, 12 total. Snapshots: 0. Time: 1.42s` | ✅ PASS |
15
- | **Full Suite** | `npx jest --testPathIgnorePatterns="dotify-api"` | `Test Suites: 48 passed, 48 total. Tests: 382 passed.` | ✅ PASS |
16
- | **TypeScript** | `npx tsc --noEmit` | `Exit code 0. Zero errors.` | ✅ PASS |
17
- | **Linter** | `npx eslint --fix src/server/attendance-confirmations/**` | `0 errors, 0 warnings found.` | ✅ PASS |
18
-
19
- ---
20
-
21
- ## 3. Goal Contract Compliance Audit
22
-
23
- | Criterion | Verified By Test / Artifact | Result |
24
- |---|---|:---:|
25
- | **AC-1**: Normal hours weekday calculation | `resolve-display-status.test.ts > normal hours` | ✅ PASS |
26
- | **AC-2**: Weekend & duration > 8 handling | `resolve-display-status.test.ts > weekend overtime` | ✅ PASS |
27
- | **AC-3**: Non-normal hours employee rules | `resolve-display-status.test.ts > shift worker` | ✅ PASS |
28
- | **AC-4**: Null & undefined timeEntities safety | `resolve-display-status.test.ts > null safety` | ✅ PASS |
29
- | **AC-5**: API Contract Preservation | `tRPC router typecheck` | ✅ PASS |
30
-
31
- ---
32
-
33
- ## 4. Finding Triage Audit
34
-
35
- - **COR-001 (High - Null Safety)**: Maker applied null coalescing in Iteration 2. Verified via fresh test execution. **Status: RESOLVED & VERIFIED**.
36
- - **MAINT-001 (Low - Factory Suggestion)**: Overridden by Judge as invalid speculative nitpick. **Status: DISMISSED / INVALID**.
37
-
38
- ---
39
-
40
- ## 5. Formal Conclusion & Hand-off
41
-
42
- The Definition of Done has been 100% satisfied with reproducible evidence.
43
- **Authorized next action**: Proceed to [DOT Delivery Adapter](file:///Users/egagofur/Development/work/ai-engineering-loop/adapters/dot/README.md) for GitLab MR generation, multi-branch cherry-picking, Coreview triage, and Mattermost notification.