@nurix/etna 0.10.1 → 0.13.0
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.
- package/data/harnesses/code/CLAUDE.md +22 -13
- package/data/harnesses/code/agents/brainstorm.md +3 -3
- package/data/harnesses/code/agents/change-review.md +190 -21
- package/data/harnesses/code/agents/harness-manager.md +22 -12
- package/data/harnesses/code/agents/maintenance.md +5 -31
- package/data/harnesses/code/agents/performance-review.md +219 -0
- package/data/harnesses/code/agents/spec-mode.md +1 -1
- package/data/harnesses/code/skills/boundary/SKILL.md +245 -0
- package/data/harnesses/code/skills/boundary/references/boundary-taxonomy.md +666 -0
- package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/README.md +14 -14
- package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/SKILL.md +14 -14
- package/data/harnesses/code/skills/documentation/SKILL.md +4 -4
- package/data/harnesses/code/skills/documentation/references/templates.md +7 -25
- package/package.json +1 -1
- package/data/harnesses/code/agents/boundary-mapper.md +0 -114
- package/data/harnesses/code/agents/contract-monitor.md +0 -66
- package/data/harnesses/code/agents/dep-health.md +0 -149
- package/data/harnesses/code/agents/git-history.md +0 -202
- package/data/harnesses/code/agents/review.md +0 -110
- package/data/harnesses/code/scripts/build-ownership-index.sh +0 -148
- package/data/harnesses/code/scripts/check-doc-drift.sh +0 -135
- package/data/harnesses/code/skills/introspect/SKILL.md +0 -136
- /package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/greenfield.md +0 -0
- /package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/backlog.md +0 -0
- /package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/decisions.md +0 -0
- /package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/doctrine.md +0 -0
- /package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/glossary.md +0 -0
- /package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/inventory.md +0 -0
- /package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/milestones.md +0 -0
- /package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/non-goals.md +0 -0
- /package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/plan-doc.md +0 -0
- /package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/questions.md +0 -0
- /package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/references.md +0 -0
- /package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/rejected.md +0 -0
- /package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/state.md +0 -0
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# scripts/check-doc-drift.sh - Detect potentially stale docs based on recent code changes
|
|
3
|
-
# plugins: [nurix-harness]
|
|
4
|
-
|
|
5
|
-
set -euo pipefail
|
|
6
|
-
|
|
7
|
-
DAYS="${1:-14}"
|
|
8
|
-
# Resolve the repo root from this script's own location — it lives at either
|
|
9
|
-
# <root>/scripts/ (kit source) or <root>/.claude/scripts/ (installed into a
|
|
10
|
-
# project). Strip whichever suffix applies; works regardless of git or cwd,
|
|
11
|
-
# and stays correct when the harness sits in a monorepo subdirectory.
|
|
12
|
-
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
13
|
-
case "$SCRIPT_DIR" in
|
|
14
|
-
*/.claude/scripts) REPO_ROOT="${SCRIPT_DIR%/.claude/scripts}" ;;
|
|
15
|
-
*/scripts) REPO_ROOT="${SCRIPT_DIR%/scripts}" ;;
|
|
16
|
-
*) REPO_ROOT="$(dirname "$SCRIPT_DIR")" ;;
|
|
17
|
-
esac
|
|
18
|
-
FEATURES_DIR="$REPO_ROOT/docs/features"
|
|
19
|
-
TMP_OWNS=$(mktemp)
|
|
20
|
-
TMP_STALE=$(mktemp)
|
|
21
|
-
TMP_UNOWNED=$(mktemp)
|
|
22
|
-
trap 'rm -f "$TMP_OWNS" "$TMP_STALE" "$TMP_UNOWNED"' EXIT
|
|
23
|
-
|
|
24
|
-
echo "Checking for doc drift over the last $DAYS days..."
|
|
25
|
-
echo ""
|
|
26
|
-
|
|
27
|
-
# Extract owns patterns from a markdown file
|
|
28
|
-
extract_owns() {
|
|
29
|
-
local file="$1"
|
|
30
|
-
awk '
|
|
31
|
-
/^---$/ { fm++; next }
|
|
32
|
-
fm == 1 && /^owns:/ { in_owns = 1; next }
|
|
33
|
-
fm == 1 && in_owns && /^ +- / {
|
|
34
|
-
sub("^ +- ", "")
|
|
35
|
-
gsub(/^[ \t]+|[ \t]+$/, "")
|
|
36
|
-
print
|
|
37
|
-
next
|
|
38
|
-
}
|
|
39
|
-
fm == 1 && in_owns && /^[a-z]/ { exit }
|
|
40
|
-
fm >= 2 { exit }
|
|
41
|
-
' "$file"
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
# Get recently changed files
|
|
45
|
-
changed_files=$(cd "$REPO_ROOT" && git log --since="$DAYS days ago" --name-only --pretty=format:"" | sort -u | grep -v '^$' || true)
|
|
46
|
-
|
|
47
|
-
if [ -z "$changed_files" ]; then
|
|
48
|
-
echo "No files changed in the last $DAYS days."
|
|
49
|
-
exit 0
|
|
50
|
-
fi
|
|
51
|
-
|
|
52
|
-
changed_count=$(echo "$changed_files" | wc -l | tr -d ' ')
|
|
53
|
-
echo "Found $changed_count changed files in the last $DAYS days."
|
|
54
|
-
echo ""
|
|
55
|
-
|
|
56
|
-
# Build ownership map: pattern\tdoc
|
|
57
|
-
find "$FEATURES_DIR" -name "*.md" ! -name "README.md" -print0 | sort -z | while IFS= read -r -d '' file; do
|
|
58
|
-
rel_path="${file#$REPO_ROOT/}"
|
|
59
|
-
extract_owns "$file" | while IFS= read -r pattern; do
|
|
60
|
-
[ -z "$pattern" ] && continue
|
|
61
|
-
printf '%s\t%s\n' "$pattern" "$rel_path" >> "$TMP_OWNS"
|
|
62
|
-
done
|
|
63
|
-
done
|
|
64
|
-
|
|
65
|
-
# Check each changed file against ownership
|
|
66
|
-
echo "$changed_files" | while IFS= read -r changed_file; do
|
|
67
|
-
[ -z "$changed_file" ] && continue
|
|
68
|
-
# Skip non-source files
|
|
69
|
-
case "$changed_file" in
|
|
70
|
-
docs/*|.claude/*|.github/*|node_modules/*|package*.json|*.lock*|*.config*) continue ;;
|
|
71
|
-
esac
|
|
72
|
-
|
|
73
|
-
found_owner=0
|
|
74
|
-
while IFS=$'\t' read -r pattern doc; do
|
|
75
|
-
prefix="${pattern%%\*\**}"
|
|
76
|
-
prefix="${prefix%%\**}"
|
|
77
|
-
case "$changed_file" in
|
|
78
|
-
${prefix}*)
|
|
79
|
-
found_owner=1
|
|
80
|
-
# Check if the doc was also modified recently
|
|
81
|
-
if ! echo "$changed_files" | grep -q "^${doc}$"; then
|
|
82
|
-
printf '%s\t%s\n' "$doc" "$changed_file" >> "$TMP_STALE"
|
|
83
|
-
fi
|
|
84
|
-
break
|
|
85
|
-
;;
|
|
86
|
-
esac
|
|
87
|
-
done < "$TMP_OWNS"
|
|
88
|
-
|
|
89
|
-
if [ "$found_owner" -eq 0 ]; then
|
|
90
|
-
case "$changed_file" in
|
|
91
|
-
src/*|app/*|packages/*) echo "$changed_file" >> "$TMP_UNOWNED" ;;
|
|
92
|
-
esac
|
|
93
|
-
fi
|
|
94
|
-
done
|
|
95
|
-
|
|
96
|
-
# Report stale docs
|
|
97
|
-
if [ -s "$TMP_STALE" ]; then
|
|
98
|
-
echo "## Potentially Stale Docs"
|
|
99
|
-
echo ""
|
|
100
|
-
echo "These docs own code that changed recently, but the docs themselves were not updated:"
|
|
101
|
-
echo ""
|
|
102
|
-
current_doc=""
|
|
103
|
-
sort "$TMP_STALE" | while IFS=$'\t' read -r doc file; do
|
|
104
|
-
if [ "$doc" != "$current_doc" ]; then
|
|
105
|
-
[ -n "$current_doc" ] && echo ""
|
|
106
|
-
echo "**$doc**"
|
|
107
|
-
current_doc="$doc"
|
|
108
|
-
fi
|
|
109
|
-
echo " - $file"
|
|
110
|
-
done
|
|
111
|
-
echo ""
|
|
112
|
-
else
|
|
113
|
-
echo "## No Stale Docs Detected"
|
|
114
|
-
echo ""
|
|
115
|
-
echo "All docs whose owned code changed were also updated."
|
|
116
|
-
fi
|
|
117
|
-
|
|
118
|
-
echo ""
|
|
119
|
-
|
|
120
|
-
# Report unowned files
|
|
121
|
-
if [ -s "$TMP_UNOWNED" ]; then
|
|
122
|
-
unowned_count=$(wc -l < "$TMP_UNOWNED" | tr -d ' ')
|
|
123
|
-
echo "## Unowned Changed Files ($unowned_count)"
|
|
124
|
-
echo ""
|
|
125
|
-
echo "These changed source files have no owning feature doc:"
|
|
126
|
-
echo ""
|
|
127
|
-
sort -u "$TMP_UNOWNED" | head -30 | while IFS= read -r file; do
|
|
128
|
-
echo "- $file"
|
|
129
|
-
done
|
|
130
|
-
if [ "$unowned_count" -gt 30 ]; then
|
|
131
|
-
echo "- ... and $((unowned_count - 30)) more"
|
|
132
|
-
fi
|
|
133
|
-
else
|
|
134
|
-
echo "## No Unowned Changed Files"
|
|
135
|
-
fi
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: introspect
|
|
3
|
-
description: Pre-implementation impact analyzer. Reads a plan in docs/history/plans/ and checks every Proposed Change against the typed boundaries in docs/boundaries/ to surface cascading risks before coding starts. Produces a severity-ranked violation report with suggested plan additions. Read-only. Triggers on "introspect", "check this plan", "impact analysis", "/introspect", "what could break", "boundary check before I start".
|
|
4
|
-
plugins: [nurix-harness]
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Introspect Skill
|
|
8
|
-
|
|
9
|
-
Pre-implementation impact analysis. Reads a plan, intersects every proposed change with the documented boundaries in `docs/boundaries/`, and surfaces cascading risk _before_ implementation. The complement to `contract-monitor`, which scans the live codebase _after_ changes land.
|
|
10
|
-
|
|
11
|
-
The skill is read-only. It does not edit the plan, modify code, or write to memory. Output is a report the user reviews and acts on.
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## When to Use
|
|
16
|
-
|
|
17
|
-
Trigger this skill when:
|
|
18
|
-
|
|
19
|
-
- The user types `/introspect`, "introspect", "check this plan", "impact analysis", "what could break"
|
|
20
|
-
- A plan exists in `docs/history/plans/` and the user is about to start implementation
|
|
21
|
-
- A plan was recently revised and the user wants to re-check boundary impact
|
|
22
|
-
|
|
23
|
-
Do not run it when:
|
|
24
|
-
|
|
25
|
-
- No `docs/boundaries/` exists, or it's empty — tell the user to baseline the typed boundaries first via the `boundary-mapper` agent (`baseline boundaries`)
|
|
26
|
-
- No plan exists — tell the user to write a plan first (documentation skill, `create plan`)
|
|
27
|
-
- The user wants post-implementation auditing — that's the `contract-monitor` agent
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
## Inputs
|
|
32
|
-
|
|
33
|
-
- **Plan path**: user-provided. If unspecified, use the most recent file in `docs/history/plans/` (sorted by filename date).
|
|
34
|
-
- **Boundaries**: every file in `docs/boundaries/` is mandatory input. Stop if the folder is missing or empty (suggest `boundary-mapper`).
|
|
35
|
-
- **Source files**: read on demand to verify intersections — never guess from plan text alone.
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Workflow
|
|
40
|
-
|
|
41
|
-
### Phase 1: Load
|
|
42
|
-
|
|
43
|
-
1. Resolve the plan path. If the user named a feature, glob `docs/history/plans/*{feature}*.md` and pick the newest.
|
|
44
|
-
2. Read the plan in full.
|
|
45
|
-
3. Confirm it has a `Status:` field. If `Complete` or `Abandoned`, ask the user whether they want to introspect a frozen plan anyway — it's usually a mistake.
|
|
46
|
-
4. Read every file in `docs/boundaries/`. For each boundary, parse the `[BOUNDARY: type · severity]` header plus: **Bounds** (the modules on each side of the contract), **Shape** (the transcribed contract, or a `file:line` pointer to self-locating code), **Invariants** (what must hold), **Blast radius** (what breaks if violated), and the **Safe-change checklist**. The severity (CRITICAL / HIGH / MED / LOW) sets the review depth for any change that touches that boundary.
|
|
47
|
-
|
|
48
|
-
### Phase 2: Parse Proposed Changes
|
|
49
|
-
|
|
50
|
-
The plan template's **Proposed Changes** subsections are load-bearing — introspect relies on their exact structure. Extract content from each:
|
|
51
|
-
|
|
52
|
-
| Subsection | What introspect uses it for |
|
|
53
|
-
|------------|------------------------------|
|
|
54
|
-
| **New Files** | New paths to check against ownership and the modules each boundary **Bounds** |
|
|
55
|
-
| **Modified Files** | Existing paths to check against boundaries that **Bound** them |
|
|
56
|
-
| **New Entities / State** | Entity strings, state slices, schema additions — checked against the `domain` and `db-schema` boundaries |
|
|
57
|
-
| **API Changes** | New or modified routes, contracts, request/response shapes — checked against the `api` / `wire-contracts` boundaries |
|
|
58
|
-
| **Cross-Module Contracts Affected** | The plan author's own admission of boundaries touched — start here, then verify |
|
|
59
|
-
|
|
60
|
-
If a subsection is missing or empty, note it in the report (the plan may be incomplete) but continue with what's there.
|
|
61
|
-
|
|
62
|
-
### Phase 3: Analyze
|
|
63
|
-
|
|
64
|
-
For each boundary × proposed change pair, check intersection:
|
|
65
|
-
|
|
66
|
-
1. **Bounds overlap** — does the change touch any module the boundary **Bounds**, or any file its **Shape** pointer (`file:line`) locates?
|
|
67
|
-
2. **Invariant overlap** — does the change introduce code shapes the boundary's **Invariants** prohibit (raw string literal where a shared constant is required, new entity type not in the canonical array, persisted field without selector fallback)?
|
|
68
|
-
3. **Shape overlap** — does the change modify the canonical **Shape** of a boundary (the `ENTITY_TYPES` array, the shared constants file, the persistence schema, the API envelope)?
|
|
69
|
-
|
|
70
|
-
Whenever an intersection is plausible from plan text, **read the actual source files** to verify. Never guess from plan text alone.
|
|
71
|
-
|
|
72
|
-
Assign severity. Anchor it to the **boundary's own severity** (it sets the floor), then adjust by the concrete risk this change carries — a change against a CRITICAL/HIGH boundary starts at that floor; downgrade only with a stated reason. The boundary's **Blast radius** is the evidence for the rating:
|
|
73
|
-
|
|
74
|
-
- **Critical** — silent data loss, corrupted persistence, broken cross-entity references
|
|
75
|
-
- **High** — stale state, broken lookups, schema selectors without fallbacks
|
|
76
|
-
- **Medium** — potential mismatch, string-coupling that's likely to drift
|
|
77
|
-
- **Low** — unlikely issue, code smell, easily caught in review
|
|
78
|
-
|
|
79
|
-
### Phase 4: Report
|
|
80
|
-
|
|
81
|
-
Produce a markdown report:
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
# Introspect — {plan filename}
|
|
85
|
-
|
|
86
|
-
Plan: {path}
|
|
87
|
-
Boundaries: {N} files evaluated
|
|
88
|
-
Intersections found: {N} ({critical}/{high}/{medium}/{low})
|
|
89
|
-
|
|
90
|
-
## Violations
|
|
91
|
-
|
|
92
|
-
| # | Boundary | Risk | Severity | Plan step |
|
|
93
|
-
|---|----------|------|----------|-----------|
|
|
94
|
-
|
|
95
|
-
## Suggested Plan Additions
|
|
96
|
-
|
|
97
|
-
For each violation, a specific recommendation:
|
|
98
|
-
|
|
99
|
-
- **Violation #1**: Add step X to Implementation Steps — {one-line action}
|
|
100
|
-
- **Violation #2**: Add to Done Criteria — {one-line check}
|
|
101
|
-
- **Violation #3**: Update Cross-Module Contracts Affected — {missing entry}
|
|
102
|
-
|
|
103
|
-
## Missing Subsections
|
|
104
|
-
|
|
105
|
-
{If any Proposed Changes subsection was empty or absent, list it here}
|
|
106
|
-
|
|
107
|
-
## New Cross-Module Contracts Detected
|
|
108
|
-
|
|
109
|
-
{If the plan introduces a cross-cutting contract not yet in `docs/boundaries/`, describe the proposed boundary (type, Bounds, Shape, suggested severity) and recommend running the `boundary-mapper` agent to formalize it — never write a boundary file directly.}
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
The severity-ranked table is the load-bearing output. Suggestions are advisory — the user decides which to fold back into the plan.
|
|
113
|
-
|
|
114
|
-
### Phase 5: Hand Off
|
|
115
|
-
|
|
116
|
-
After producing the report:
|
|
117
|
-
|
|
118
|
-
- If the user accepts a suggested plan addition, they edit the plan themselves (or invoke the documentation skill to do it). Introspect never edits plans.
|
|
119
|
-
- If new contracts are detected, suggest running the `boundary-mapper` agent to formalize them as a typed boundary — do not write to `docs/boundaries/` from this skill.
|
|
120
|
-
|
|
121
|
-
---
|
|
122
|
-
|
|
123
|
-
## Rules
|
|
124
|
-
|
|
125
|
-
- **Read-only**. Never edit the plan, source code, boundaries, or memory.
|
|
126
|
-
- **Verify against source**. Never report a violation purely from plan text — read the files the plan claims it will touch.
|
|
127
|
-
- **Plan structure is load-bearing**. If a plan was not written using the documentation skill's plan template, the Proposed Changes subsections may be missing. Note this clearly rather than fabricating intersections.
|
|
128
|
-
- **A clean report is valid**. Plans with no intersections produce an empty violations table — say so, don't pad.
|
|
129
|
-
- **Be specific**. Cite file paths, plan-step numbers, boundary names, and the exact code shape that breaks the contract.
|
|
130
|
-
- **Don't replicate contract-monitor**. Introspect checks intent (plan text). Contract-monitor checks reality (code). If the user wants to scan live code, route them to contract-monitor.
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
## Output Location
|
|
135
|
-
|
|
136
|
-
The report is returned in the chat — not written to disk. The user reviews it and folds insights back into the plan manually (or via the documentation skill).
|
|
File without changes
|
/package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/backlog.md
RENAMED
|
File without changes
|
/package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/decisions.md
RENAMED
|
File without changes
|
/package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/doctrine.md
RENAMED
|
File without changes
|
/package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/glossary.md
RENAMED
|
File without changes
|
/package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/inventory.md
RENAMED
|
File without changes
|
/package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/milestones.md
RENAMED
|
File without changes
|
/package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/non-goals.md
RENAMED
|
File without changes
|
/package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/plan-doc.md
RENAMED
|
File without changes
|
/package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/questions.md
RENAMED
|
File without changes
|
/package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/references.md
RENAMED
|
File without changes
|
/package/data/harnesses/code/skills/{technical-brainstorm → brainstorm}/templates/rejected.md
RENAMED
|
File without changes
|
|
File without changes
|