Διαμόρφωση copy-paste από την παραγωγή για επικύρωση προ-commit, σάρωση PII, διασφαλίσεις ανάπτυξης και καταγραφή συνεδρίας Πριν από έξι μήνες κράτησα μια κολλώδη σημείωση στην οθόνη μου, η οποία έλεγε: «Έχεις βάλει ταινία; Έχεις ελέγξει το κλάδο; Έχεις δει τι έχει διαγράψει;» Κάθε συνεδρία του Claude Code, οι ίδιοι χειροκίνητοι έλεγχοι. Κάθε φορά που ο Claude επεξεργάστηκε ένα αρχείο, άλλαζα σε ένα άλλο τερματικό και εκτελούσα τον μορφοποιητή. Κάθε φορά που εκτελούσε μια εντολή Bash, έψαχνα στην έξοδο αναρωτιέμαι αν κάτι άγγιζε την παραγωγή. Κάθε φορά που προσπαθούσε να διαπράξει, έλεγξα ότι ήμουν στο σωστό κλάδο πρώτα. Το πρόβλημα ήταν ότι έκανα τη δουλειά ενός υπολογιστή. Επαναλαμβανόμενο μοτίβο που ταιριάζει σε κάθε ενέργεια, εκατοντάδες φορές την ημέρα. Στη συνέχεια ανακάλυψα ότι ο Claude Code πυροδοτεί γεγονότα. Κάθε μεμονωμένη ενέργεια. κλήσεις εργαλείων, επεξεργασίες αρχείων, εντολές Bash, έναρξη συνεδρίας, λήξη συνεδρίας. Όλα αυτά. Και μπορείτε να αναχαιτίσετε οποιοδήποτε από αυτά με ένα σενάριο κελύφους. Έχει χαθεί το χαρτονόμισμα, αυτό είναι που το αντικατέστησε. Το σύστημα εκδηλώσεων για το οποίο κανείς δεν μιλάει Ο Claude Code δεν είναι απλά μια διεπαφή συνομιλίας που γράφει κώδικα. Κάτω από την επιφάνεια, εκτελεί έναν κύκλο ζωής. Ο χρήστης στέλνει μια ειδοποίηση. ο Claude αποφασίζει ποιο εργαλείο να χρησιμοποιήσει. το εργαλείο εκτελεί. ο Claude διαβάζει το αποτέλεσμα. Επαναλάβετε μέχρι να ολοκληρωθεί. Σε κάθε μετάβαση σε αυτόν τον κύκλο, ο Claude Code πυροδοτεί ένα συμβάν και μπορείτε να συνδέσετε έναν χειριστή σε οποιοδήποτε από αυτά. Τα δύο γεγονότα που μετράνε περισσότερο: Ο χειριστής σας μπορεί να ελέγξει την κλήση και να επιστρέψει μια ετυμηγορία JSON: να την επιτρέψει, να την αρνηθεί ή να παραμείνει σιωπηλός και να αφήσει την κανονική ροή αδειών να την χειριστεί. PostToolUse πυροβολεί μετά από μια επιτυχημένη κλήση εργαλείου. Ο χειριστής σας παίρνει την πλήρη έξοδο. Κάντε ό, τι θέλετε με αυτό. Lint το αρχείο. Καταχωρήστε την εντολή. Στείλτε ένα webhook. Το εργαλείο έχει ήδη τρέξει, οπότε αυτό είναι αντιδραστικό, όχι προληπτικό. Οι διαχειριστές είναι εγγεγραμμένοι στην Μπορούν να είναι εντολές shell, HTTP endpoints, ή LLM prompts. χρησιμοποιώ εντολές shell επειδή είναι γρήγορες, ανακτήσιμες και δεν απαιτούν υποδομή. .claude/settings.json Ολόκληρη η διεπαφή είναι: Claude Code αγωγών JSON στο stdin του σενάριο σας. το σενάριο σας προαιρετικά γράφει JSON σε stdout. Αυτό είναι. Εάν το σενάριο σας βγαίνει χωρίς έξοδο, Claude Code προχωρά κανονικά. Σενάριο 1: Το σενάριο πρόληψης καταστροφών Το έγραψα αυτό αφού ο Κλοντ προσπάθησε να Ένας κατάλογος κατασκευής που συνέβη να έχει ένα symlink στον αρχικό μου φάκελο. Τίποτα κακό δεν συνέβη επειδή το έπιασα στην εντολή άδειας. αλλά δεν θα έπρεπε να το πιάσω. rm -rf #!/bin/bash # .claude/hooks/guard.sh # Blocks destructive commands before they execute CMD=$(jq -r '.tool_input.command // empty') [ -z "$CMD" ] && exit 0 # Patterns I never want to run unreviewed BLOCKED_PATTERNS=( 'rm -rf' 'rm -r /' 'DROP TABLE' 'DROP DATABASE' 'truncate ' '> /dev/sd' 'mkfs\.' 'dd if=' ) for pattern in "${BLOCKED_PATTERNS[@]}"; do if echo "$CMD" | grep -qi "$pattern"; then jq -n --arg reason "Blocked: command matches dangerous pattern '$pattern'" '{ hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: $reason } }' exit 0 fi done Οκτώ μοτίβα. Θα μπορούσε να είναι ογδόντα. Το θέμα δεν είναι να απαριθμήσουμε κάθε επικίνδυνη εντολή. Το θέμα είναι να πιάσει εκείνους που έχετε προσωπικά σχεδόν τρέχει τυχαία. λίστα μου αντικατοπτρίζει τις ουλές μου. δική σας θα αντανακλά το δικό σας. Η καταχώριση στην : .claude/settings.json "PreToolUse": [ { "matcher": "Bash", "hooks": [{ "type": "command", "command": ".claude/hooks/guard.sh" }] } ] Η είναι ένα regex στο όνομα του εργαλείου. σημαίνει ότι αυτό το κέλυφος πυροδοτεί μόνο τις εντολές Bash, όχι τις επεξεργασίες αρχείων ή τις αναγνώσεις. matcher "Bash" Σενάριο 2: Ο μορφοποιητής που δεν ξεχνά ποτέ Πριν από αυτό το hook, η ροή εργασίας μου ήταν: ο Claude επεξεργάζεται το αρχείο, παρατηρώ ότι η μορφοποίηση είναι λάθος, ζητώ από τον Claude να το διορθώσει, ο Claude εκτελεί τον μορφοποιητή, αναθεωρώ τη μορφοποιημένη έκδοση. #!/bin/bash # .claude/hooks/fmt.sh # Formats files immediately after Claude edits them TOOL=$(jq -r '.tool_name // empty') [ "$TOOL" != "Edit" ] && [ "$TOOL" != "Write" ] && exit 0 FP=$(jq -r '.tool_input.file_path // .tool_input.path // empty') [ -z "$FP" ] || [ ! -f "$FP" ] && exit 0 case "${FP##*.}" in js|ts|jsx|tsx|mjs) if [ -f node_modules/.bin/prettier ]; then node_modules/.bin/prettier --write "$FP" 2>/dev/null elif command -v npx &>/dev/null; then npx prettier --write "$FP" 2>/dev/null fi ;; rs) rustfmt "$FP" 2>/dev/null ;; py) command -v ruff &>/dev/null && ruff format "$FP" 2>/dev/null command -v ruff &>/dev/null && ruff check --fix "$FP" 2>/dev/null ;; go) gofmt -w "$FP" 2>/dev/null ;; css|scss) command -v stylelint &>/dev/null && stylelint --fix "$FP" 2>/dev/null ;; esac exit 0 Αυτή η έκδοση είναι πιο εμπεριστατωμένη από το ελάχιστο παράδειγμα που βρίσκετε στην τεκμηρίωση. Ελέγχει αν ο μορφοποιητής υπάρχει πραγματικά πριν τον καλέσετε. Διαχειρίζεται το Prettier μέσω τοπικής εγκατάστασης ή npx. και για την Python επειδή η μορφοποίηση και η επικάλυψη είναι διαφορετικά πράγματα. ruff format ruff check --fix Καταχωρήστε το ως PostToolUse με ένα Το αρχείο διαμορφώνεται πριν ο Claude το διαβάσει πίσω ή προχωρήσει στην επόμενη επεξεργασία. "Edit|Write" Η σύνθετη επίδραση είναι σημαντική. Πάνω από μια εβδομάδα το μέτρησα. Χωρίς το χτύπημα, ξόδεψα κατά μέσο όρο 4 λεπτά ανά συνεδρία ζητώντας από τον Claude να διορθώσει τα προβλήματα μορφοποίησης. Με το χτύπημα, μηδέν. Πάνω από 30 συνεδρίες την εβδομάδα, δηλαδή δύο ώρες ανακτήθηκαν. Σενάριο 3: Ο μυστικός ανιχνευτής Αυτό υπάρχει εξαιτίας ενός σχεδόν λανθασμένου. ο Claude χειραγωγούσε μια ολοκλήρωση API, διάβαζε ένα αρχείο διαμόρφωσης που περιείχε ένα κλειδί API δοκιμής και συμπεριέλαβε το κλειδί στην απάντησή του. Το κλειδί ήταν για ένα περιβάλλον στάθμευσης και περιστρέφτηκε την επόμενη μέρα. Αλλά η αρχή με ενοχλούσε. #!/bin/bash # .claude/hooks/secrets.sh # Scans tool output for credential-shaped strings OUTPUT=$(jq -r '.tool_output // empty') [ -z "$OUTPUT" ] && exit 0 ALERTS="" # AWS keys (AKIA...) echo "$OUTPUT" | grep -qE 'AKIA[0-9A-Z]{16}' && ALERTS="$ALERTS aws_key" # Generic API key patterns (long hex/base64 after common key names) echo "$OUTPUT" | grep -qiE '(api_key|apikey|secret_key|access_token|auth_token)["\x27: =]+[A-Za-z0-9+/]{20,}' && ALERTS="$ALERTS api_credential" # Private key headers echo "$OUTPUT" | grep -q 'BEGIN.*PRIVATE KEY' && ALERTS="$ALERTS private_key" # JWT tokens echo "$OUTPUT" | grep -qE 'eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.' && ALERTS="$ALERTS jwt_token" # Connection strings with passwords echo "$OUTPUT" | grep -qiE '(postgresql|mysql|mongodb|redis)://[^:]+:[^@]+@' && ALERTS="$ALERTS connection_string" if [ -n "$ALERTS" ]; then TS=$(date '+%H:%M:%S') TOOL=$(jq -r '.tool_name // unknown') echo "[$TS] SECRET_ALERT in $TOOL:$ALERTS" >> .claude/secret-alerts.log echo "WARNING: potential credential in $TOOL output ($ALERTS)" >&2 fi exit 0 Αυτό δεν είναι ένα υποκατάστατο για τη σωστή διαχείριση μυστικών. Είναι ένα tripwire. Πιάζει τα προφανή πρότυπα: κλειδιά πρόσβασης AWS, πράγματα που μοιάζουν με διαπιστευτήρια API, ιδιωτικά μπλοκ κλειδιών, JWTs, αλυσίδες σύνδεσης βάσης δεδομένων με ενσωματωμένους κωδικούς πρόσβασης. Όταν καίγεται, καταγράφει και εκτυπώνει μια προειδοποίηση στο stderr. Δεν εμποδίζει τίποτα. Το μπλοκάρισμα ενός ψευδούς θετικού θα διακόψει τη ροή σας. Η καταγραφή ενός αληθινού θετικού σας δίνει κάτι να ερευνήσετε στο τέλος της συνεδρίας. .claude/secret-alerts.log Η αναθεώρηση Οι περισσότερες καταχωρήσεις είναι ψευδώς θετικές (δοκιμαστικές εγγραφές, παραδείγματα τεκμηρίωσης). Περίπου μία φορά την εβδομάδα, μία είναι αρκετά πραγματική για να δικαιολογήσει την περιστροφή ενός διαπιστευτηρίου ή την ενημέρωση ενός .gitignore. secret-alerts.log Σκηνοθεσία: The Branch Cop Σύντομη, αιχμηρή και γεννημένη από ένα πραγματικό λάθος. Ζήτησε από τον Κλοντ να πιέσει μια γρήγορη επιδιόρθωση και έτρεξε. πριν καταγράψω τι συνέβαινε. Η ώθηση πέρασε. Η CI ήταν πράσινη. Δεν έγινε καμία ζημιά. Αλλά η δέσμευση δεν έπρεπε να προσγειωθεί στο κύριο χωρίς PR. main git push origin main #!/bin/bash # .claude/hooks/no-push-main.sh # Prevents git push to main/master/production branches CMD=$(jq -r '.tool_input.command // empty') echo "$CMD" | grep -q 'git push' || exit 0 BRANCH=$(git branch --show-current 2>/dev/null) PROTECTED="main master production release" for b in $PROTECTED; do if [ "$BRANCH" = "$b" ]; then jq -n --arg branch "$BRANCH" '{ hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: ("Push to " + $branch + " blocked. Create a feature branch first.") } }' exit 0 fi done # Also block force push to any branch if echo "$CMD" | grep -qE 'push.*(-f|--force)'; then jq -n '{ hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: "Force push blocked. Use --force-with-lease if you must." } }' fi Δύο φύλακες σε ένα σενάριο. Καμία ώθηση σε προστατευόμενα κλαδιά. Καμία δύναμη που πιέζει σε οποιοδήποτε κλάδο. Ο δεύτερος κανόνας είναι προαιρετικός, αλλά το κρατάω επειδή οι πιέσεις δύναμης είναι το είδος του πράγματος που θα πρέπει να απαιτήσει από εσάς να πληκτρολογήσετε την εντολή μόνοι σας, με πλήρη επίγνωση του τι κάνετε. Ο Claude χειρίζεται την άρνηση με ευγένεια. Βλέπει τον λόγο, προτείνει τη δημιουργία ενός κλάδου χαρακτηριστικών και προχωρά στη σωστή διαδρομή. Σκηνοθεσία: The Black Box Recorder Κάθε κλήση εργαλείου. κάθε είσοδος. κάθε έξοδος. χρονικά σφραγισμένο και συνημμένο σε ένα αρχείο καταγραφής. Αυτό είναι το κέικ που συνιστώ συχνότερα στις ομάδες επειδή απαντά στην ερώτηση που ρωτάτε πάντα μετά από κάτι που πάει στραβά: "Τι ακριβώς έκανε ο Claude;" #!/bin/bash # .claude/hooks/record.sh # Logs every tool call to a structured audit file TS=$(date '+%Y-%m-%d %H:%M:%S') TOOL=$(jq -r '.tool_name // "unknown"') SESSION=$(jq -r '.session_id // "unknown"') # Compact input (one line, no whitespace bloat) INPUT=$(jq -c '.tool_input // {}') # Truncate output to prevent log bloat (first 500 chars) OUTPUT=$(jq -r '.tool_output // empty' | head -c 500) # Tab-separated for easy parsing with awk/cut printf '%s\t%s\t%s\t%s\t%s\n' \ "$TS" "$SESSION" "$TOOL" "$INPUT" "$OUTPUT" \ >> .claude/session-log.tsv exit 0 Διαχωρισμένα από καρτέλες, όχι JSON. Σκόπιμη επιλογή. Τα αρχεία TSV είναι εύχρηστα, ταξινομητά και κοπής με τα τυπικά εργαλεία Unix. Πρέπει να δείτε κάθε εντολή Bash από σήμερα; grep "$(date +%Y-%m-%d)" .claude/session-log.tsv | grep "Bash" | cut -f4 Πρέπει να μετρήσετε πόσες επεξεργασίες αρχείων έκανε ο Claude αυτή την εβδομάδα; grep -c "Edit\|Write" .claude/session-log.tsv Το πεδίο εξόδου μειώνεται σε 500 χαρακτήρες για να αποφευχθούν αρχεία καταγραφής πολλαπλών megabyte όταν ο Claude διαβάζει μεγάλα αρχεία. Εάν χρειάζεστε πλήρη εξαγωγή, μεταβείτε σε αρχεία καταγραφής ανά συνεδρία: αντικαταστήστε το όνομα αρχείου με . .claude/logs/session-${SESSION}.tsv Για τις ομάδες που χρειάζονται κεντρική καταγραφή, αντικαταστήστε το συνημμένο αρχείου με μια κλειδαριά HTTP που δείχνει στην υποδομή καταγραφής σας. Το φορτίο χρήσης JSON που στέλνει ο Claude Code περιέχει όλα όσα καταγράφει αυτό το σενάριο, καθώς και πρόσθετο πλαίσιο όπως ο κατάλογος εργασίας και η διαμόρφωση εργαλείων. Το συνδυασμένο αρχείο ρυθμίσεων Όλα τα πέντε σενάρια, συνδεδεμένα μαζί: { "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": ".claude/hooks/guard.sh" }, { "type": "command", "command": ".claude/hooks/no-push-main.sh" } ] } ], "PostToolUse": [ { "matcher": "Edit|Write", "hooks": [ { "type": "command", "command": ".claude/hooks/fmt.sh" } ] }, { "matcher": "", "hooks": [ { "type": "command", "command": ".claude/hooks/secrets.sh" }, { "type": "command", "command": ".claude/hooks/record.sh" } ] } ] } } Αντιγράψτε το JSON σε Δημιουργήστε τα πέντε σενάρια σε • Τρέξιμο Ο Ντον. .claude/settings.json .claude/hooks/ chmod +x .claude/hooks/*.sh ΠΡΩΤΟΒΟΥΛΙΟ ΠΕΡΙΕΧΟΜΕΝΟ ΣΤΗΝ ΑΡΧΗ: Και τα δύο και αξιολογήσει κάθε εντολή Bash. Εάν είτε επιστρέψει μια άρνηση, η εντολή είναι μπλοκαρισμένη. PostToolUse hooks τρέχει επίσης με τη σειρά, αλλά δεν μπορούν να μπλοκάρουν τίποτα. το εργαλείο έχει ήδη εκτελεστεί. guard.sh no-push-main.sh Ο κενός συνδυασμός στη δεύτερη είσοδο PostToolUse σημαίνει και Φωτιά σε κάθε κλήση εργαλείου, όχι μόνο επεξεργασίες αρχείων. Αυτό είναι σκόπιμο. θέλω να σαρώσω την έξοδο Bash για διαπιστευτήρια και θέλω να καταγράψω τα πάντα, ανεξάρτητα από τον τύπο του εργαλείου. secrets.sh record.sh Τι έμαθα τρέχοντας αυτά για έξι μήνες Όλα τα άλλα είναι ασφάλιση. Ο μορφοποιητής είναι μια άμεση, μετρήσιμη εξοικονόμηση χρόνου. Εγκαταστήστε αυτό το πρώτο, ακόμα και αν αγνοήσετε τα υπόλοιπα. The formatter hook pays for itself on day one. Θα προτιμούσα να ελέγχω δέκα ψευδείς συναγερμούς την εβδομάδα παρά να χάσω ένα πραγματικό διαπιστευτήριο.Η ανασκόπηση του αρχείου καταγραφής διαρκεί 30 δευτερόλεπτα. False positives in the secret scanner are fine. Κάθε λίγες εβδομάδες προσθέτω ένα μοτίβο μετά από μια σχεδόν απώλεια. Τώρα έχει οκτώ μοτίβα. Σε έξι μήνες θα έχει είκοσι. Αυτό είναι το σημείο. Συγκεντρώνει τις θεσμικές γνώσεις της ομάδας σας για το τι δεν πρέπει ποτέ να τρέχει χωρίς ανασκόπηση. The guard script needs to evolve. rm -rf Αλλά όταν κάτι πάει στραβά, έχοντας μια πλήρη καταγραφή κάθε δράσης που πήρε ο Claude μετατρέπει μια διερεύνηση δύο ωρών σε μια πενταλεπτή σύλληψη. The audit log is most valuable after incidents. Κάθε σύνδεσμος PreToolUse προσθέτει καθυστέρηση σε κάθε κλήση εργαλείου. Τα σενάρια μου guard και branch-cop τρέχουν σε λιγότερο από 5ms το καθένα. Ο μορφοποιητής είναι ο πιο αργός σε 50-200ms ανάλογα με το μέγεθος του αρχείου, αλλά τρέχει PostToolUse έτσι ώστε να μην μπλοκάρει τον αγωγό. Εάν ο σύνδεσμος σας καλεί ένα εξωτερικό API, χρησιμοποιήστε PostToolUse ή αποδεχτείτε την καθυστέρηση. Keep hooks fast. Το Sticky Note έχει φύγει Η παρακολούθηση που ζούσε στο κεφάλι μου τώρα ζει σε πέντε σενάρια κελύφους συνολικά 150 γραμμές. τρέχουν σε κάθε κλήση εργαλείου χωρίς τη συμμετοχή μου. Πιάζουν πράγματα που θα μου έλειπαν όταν είμαι κουρασμένος στο τέλος μιας μακράς συνεδρίας. Οι βοηθοί κωδικοποίησης AI είναι ισχυροί. αλλά η ισχύς χωρίς φυλακές είναι μόνο ο κίνδυνος που δεν έχετε μετρήσει ακόμα. Πέντε σενάρια, δέκα λεπτά εγκατάστασης και ο κίνδυνος πέφτει σχεδόν στο μηδέν. Το κολλώδες σημείωμα έχει αντικατασταθεί από κάτι καλύτερο. Κάτι που δεν βασίζεται σε μένα να θυμάμαι να το κοιτάξω.