{"id":37779901,"url":"https://github.com/erkinalp/invalid-bitting-generator","last_synced_at":"2026-01-16T15:04:09.471Z","repository":{"id":318107439,"uuid":"1069727515","full_name":"erkinalp/invalid-bitting-generator","owner":"erkinalp","description":"A tool to create terminally invalid key bittings that cannot be etched further to make into a valid key","archived":false,"fork":false,"pushed_at":"2025-10-22T19:51:17.000Z","size":39,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"default","last_synced_at":"2025-10-22T21:36:01.474Z","etag":null,"topics":["difference-constraints","door-lock","educational-tool","locksmith","prankware"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/erkinalp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-04T14:01:12.000Z","updated_at":"2025-10-22T19:51:20.000Z","dependencies_parsed_at":"2025-10-09T00:02:58.300Z","dependency_job_id":null,"html_url":"https://github.com/erkinalp/invalid-bitting-generator","commit_stats":null,"previous_names":["erkinalp/invalid-bitting-generator"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/erkinalp/invalid-bitting-generator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erkinalp%2Finvalid-bitting-generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erkinalp%2Finvalid-bitting-generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erkinalp%2Finvalid-bitting-generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erkinalp%2Finvalid-bitting-generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erkinalp","download_url":"https://codeload.github.com/erkinalp/invalid-bitting-generator/tar.gz/refs/heads/default","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erkinalp%2Finvalid-bitting-generator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28479406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["difference-constraints","door-lock","educational-tool","locksmith","prankware"],"created_at":"2026-01-16T15:04:09.376Z","updated_at":"2026-01-16T15:04:09.456Z","avatar_url":"https://github.com/erkinalp.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Terminally invalid key bittings: research, analysis, and generator\n\nWhat’s new\n- Added modeling for manufacturer constraints beyond MACS:\n  - No-cut/forbidden stations\n  - Station-specific depth ceilings\n  - Stop type (shoulder vs tip) and minimum first station\n- Added presets for pin tumbler locks: US, Euro, Kwikset SmartKey 6-key used in 5-pin plug, Schlage Everest full-size, Schlage Everest 29 SL tip-read, BEST A2 tip, Yale KeyMark conventional, Yale IC A2 tip, ASSA ABLOY Yale conventional\n- Expanded warded lock presets with 7 families: binary, multiward (4/8-depth), lever (4/6-ward), skeleton key, padlock variants\n- Expanded disc tumbler lock presets with 11 families: Abloy Classic, Protec2, Disklock, Exec, Profile, Protec (various disc counts)\n- Expanded tubular lock presets with 7 families: 4-pin through 10-pin, Chicago 7-pin, Ace 8-pin variants\n- Expanded wafer tumbler lock presets with 12 families: shallow/deep, automotive (GM/Ford/Chrysler), desk drawer, cabinet, mailbox\n- Added CLI: check, repair, list-terminal, enumerate, presets\n\nKey findings with citations\n- Kwikset SmartKey forbidden station for 5‑pin plug when gauging a 6‑pin key: “0-position on the key is not used… do not gauge the 0-position.”\n  - /home/ubuntu/research/locks/kwikset_rekey_manual.txt lines 639-646\n- Schlage Everest full-size OEM data: MACS=7; Increment=0.15\"; Spacing tolerance ±0.001\"; Depth tolerance +.002/−0.\n  - /home/ubuntu/research/locks/schlage_everest_fullsize_manual.txt lines 909-931\n- Schlage Everest cutting guidance: first-cut positioning can be mis-set if carriage travel is restricted by bow geometry; confirms setup/stop constraints matter.\n  - /home/ubuntu/research/locks/schlage_everest_fullsize_manual.txt lines 1403-1409\n- Schlage catalog: shoulder stop is the datum while bittings are read tip-to-bow for certain families; establishes stop rule governing first-station permissibility.\n  - /home/ubuntu/research/locks/schlage_catalog.txt lines 1636-1643\n- Yale KeyMark Service Manual: A2 pinning with MACS: 9, Increment: .0125\", Depth Tol ±0.0015\", Spacing Tol ±0.0010\", and “SPACING FROM THE SHOULDER” indicating shoulder-stop stationing.\n  - URL: https://www.sopl.us/uploads/1/3/0/1/1301029/yale_keymark_service_manual.pdf\n  - Extracted: /home/ubuntu/research/locks/yale_keymark_manual.txt lines 456-463, 489-491\n- ASSA ABLOY Yale Cylinders \u0026 Keys Catalog: SFIC “keys are cut from tip to bow” and section/read conventions; supports tip-read preset and general Yale conventions.\n  - URL: https://www.assaabloy.com/hk/en/product-assets/cylinder/yale4/assets/documents/Yale_Cylinders_and_Keys_Catalog.pdf\n  - Extracted: /home/ubuntu/research/locks/yale_cylinders_keys_catalog.txt lines 1258-1259, 1328-1329\n\n- best_a2_tip: BEST A2, tip-stop preset (A2 increment context), with a conservative minimum first station from tip\n\n- Schlage Everest 29 SL: read standard cuts with key gauge starting at the tip; SFIC A2 uses 0.0125\" increment (context for increments/standards).\n  - /home/ubuntu/research/locks/schlage_everest29_sl_manual.txt lines 2514-2517 and 2123-2128\n\nWhy terminal invalidity exists\n- MACS + global depth range alone is monotone under deepening; any sequence within max depth can be deepened to satisfy MACS.\n- Terminal invalidity arises when constraints are not monotone under deepening:\n  - A cut at a forbidden/no‑cut station cannot be removed by deepening.\n  - A cut before the minimum allowed first station for the stop type cannot be moved by deepening.\n  - A station-specific ceiling lower than global max makes any deeper cut at that station unfixable by deepening.\n\nModel\n- KeySystem fields now include:\n  - stop_type: shoulder or tip\n  - min_first_station_index: earliest allowed station index for a cut\n  - no_cut_mask: per-station boolean disallow\n  - station_max_ceiling: per-station maximum depths\n  - max_consecutive_repeats: maximum allowed consecutive identical cuts\n- Validation checks these before and after MACS repair. Repair is linear-time propagation; no recursion.\n\nTheoretical Foundation\nThe tool now supports two equivalent implementations for detecting terminally invalid bittings:\n\n1. Iterative constraint propagation (default): Forward and backward passes that propagate MACS constraints until convergence. O(n²) time complexity in worst case.\n\n2. Difference constraints solver (--use-bellman-ford): Based on the theory that terminal invalidity is equivalent to membership in the complement of the upward-closure of valid bittings. This formulation models the problem as a difference constraint system where:\n   - Variables y[i] represent (possibly deepened) depths at each station\n   - Constraints include: y[i] \u003e= x[i] (deepening only), y[i] \u003c= ceiling[i] (bounds), |y[i+1] - y[i]| \u003c= MACS (adjacency)\n   - The system is solved using constraint propagation inspired by Bellman-Ford shortest paths algorithm\n   - A bitting is terminally invalid if and only if no solution exists (negative cycle analog)\n\nKey insight: Deepening-only repair is a constraint satisfaction problem. MACS + global bounds alone is monotone under deepening (always repairable), but additional constraints like forbidden stations, station-specific ceilings, and first-station rules break monotonicity and create terminal invalidity.\n\nReferences:\n- Difference constraints: Cormen et al., Introduction to Algorithms, Chapter 24.4\n- Upward-closure interpretation: Order theory, upper sets (Wikipedia: https://en.wikipedia.org/wiki/Upper_set)\n- MACS specification: Allegion Knowledge Base (https://kc.allegion.com/kb/article/what-is-the-maximum-adjacent-cut-specification-or-macs/)\n\nPresets\n\nPin Tumbler Locks\n- us: generic 5-pin, depths 1..7, MACS 2\n- euro: generic 5-pin, depths 1..10, MACS 2\n- kwikset_6in5: 6-pin key used in 5-pin plug; station 0 is no-cut\n- schlage_everest_full: MACS 7, shoulder stop\n- schlage_everest29_sl_tip: MACS 7, tip-read; min_first_station_index defaults to 1 to demonstrate tip-stop constraints\n- best_a2_tip: BEST A2, tip-stop; conservative min-first-station from tip\n- yale_keymark: Yale KeyMark conventional, shoulder stop; stationing by shoulder datum\n- yale_ic_a2_tip: Yale SFIC A2-style tip-read; min_first_stn=1\n- assa_abloy_yale: Yale conventional under ASSA ABLOY catalog; shoulder stop\n\nWarded Locks (Realistic Variants with Terminal Invalidity)\n- warded_multiward_4: 6-position multiward lock, depths 0..3, MACS 3\n  - Multiple ward depths for increased complexity\n  - Intermediate security warded lock configuration\n- warded_multiward_8: 6-position multiward lock, depths 0..7, MACS 7\n  - Complex ward patterns with 8 depth variations\n  - Maximum complexity for warded lock designs\n- warded_lever_4: 5-position lever warded lock, depths 0..3, MACS 3\n  - Lever-based ward obstructions\n  - Common in historical door locks and padlocks\n- warded_lever_6: 5-position lever warded lock, depths 0..5, MACS 5\n  - Extended depth range for lever ward configurations\n  - Higher security variant with 6 depth levels\n- warded_skeleton_simple: 3-position skeleton key system, depths 0..1, MACS 1\n  - Simplified ward pattern for skeleton key compatibility\n  - Minimal ward obstructions, very low security\n- warded_padlock_4ward: 4-position padlock warded lock, depths 0..3, MACS 3\n  - Common Master Lock style warded padlock\n  - 4-ward configuration for outdoor applications\n- warded_lever_tumbler_5: 5-position lever tumbler warded lock, depths 0..4, MACS 2\n  - Lever-based warding mechanism with 5 depth levels\n  - Creates terminal invalidity due to MACS \u003c depth range\n- warded_master_padlock: 4-position Master-style padlock, depths 0..5, MACS 2\n  - Realistic Master Lock warded padlock configuration\n  - 6 depth levels with restrictive MACS creates terminal invalidity\n- warded_door_mortise: 6-position door mortise warded lock, depths 0..7, MACS 3\n  - Traditional door lock ward configuration\n  - 8 depth levels with medium MACS for realistic complexity\n- warded_cabinet_complex: 5-position complex cabinet lock, depths 0..6, MACS 2\n  - High-complexity cabinet warded lock\n  - 7 depth levels with low MACS creates many terminal sequences\n\nWarded Locks (NO Terminal Invalidity - Educational)\n- warded_binary: 4-position binary warded lock, depths 0..1, MACS 1\n  - Simple ward configurations with binary notch patterns\n  - NO terminal invalidity: depth range equals MACS\n  - Educational example showing boundary case\n- warded_skeleton_simple: 3-position skeleton key system, depths 0..1, MACS 1\n  - Simplified ward pattern for skeleton key compatibility\n  - NO terminal invalidity: minimal depth range equals MACS\n  - Educational example of lock with no invalid configurations\n\nDisc Tumbler Locks (Abloy)\n- disc_abloy_classic_6: 6-disc Abloy Classic, depths 0..5 (6 positions), MACS 5\n  - Original Abloy design with rotating discs at 18° increments (0° to 90°)\n  - Semi-cylindrical key with angled notches\n  - Constraint: No more than 3 consecutive positions can have the same cut\n  - Reference: https://www.lockwiki.com/index.php/Abloy_Classic\n- disc_abloy_classic_10: 10-disc Abloy Classic, depths 0..5 (6 positions), MACS 5\n  - Extended disc count for higher security (5-11 discs possible)\n  - Uses same 6 angular positions as 6-disc variant\n- disc_abloy_protec2_6: 6-disc Abloy Protec2, depths 0..9, MACS 8\n  - Modern high-security disc detainer design\n  - Improved false gate protection\n- disc_abloy_protec2_10: 10-disc Abloy Protec2, depths 0..11, MACS 10\n  - Maximum security disc tumbler configuration\n  - Extended depth range and disc count\n- disc_abloy_disklock_6: 6-disc Abloy Disklock, depths 0..11, MACS 10\n  - Disklock/Disklock Pro series for high-security applications\n  - 12 depth positions for increased key combinations\n- disc_abloy_disklock_10: 10-disc Abloy Disklock, depths 0..11, MACS 10\n  - Extended disc count Disklock variant\n  - Used in high-security padlocks and cylinders\n- disc_abloy_exec_6: 6-disc Abloy Exec, depths 0..11, MACS 10\n  - Exec series medium-high security disc detainer\n  - Designed for commercial and institutional use\n- disc_abloy_exec_10: 10-disc Abloy Exec, depths 0..11, MACS 10\n  - Extended disc count for higher security applications\n  - Common in European commercial installations\n- disc_abloy_profile_6: 6-disc Abloy Profile, depths 0..9, MACS 8\n  - Profile/High Profile series for general commercial use\n  - Intermediate security level between Classic and Protec\n- disc_abloy_profile_10: 10-disc Abloy Profile, depths 0..9, MACS 8\n  - Extended disc configuration for Profile series\n  - Widely used in Nordic countries for commercial locks\n- disc_abloy_protec_8: 8-disc Abloy Protec, depths 0..11, MACS 10\n  - Original Protec series (predecessor to Protec2)\n  - High security disc detainer with 8-disc configuration\n\nTubular Pin Tumbler Locks\n- tubular_4pin: 4-pin tubular lock, depths 0..9, MACS 8\n  - Minimal tubular configuration for basic security\n  - Used in some simple vending machine applications\n- tubular_6pin: 6-pin tubular lock, depths 0..9, MACS 8\n  - Common in smaller diameter tubular locks\n  - Used in some computer locks and small equipment\n- tubular_7pin: 7-pin tubular lock, depths 0..9, MACS 8\n  - Circular pin arrangement (common in vending machines)\n  - Also known as Ace lock or circle pin tumbler\n  - Reference: https://en.wikipedia.org/wiki/Tubular_pin_tumbler_lock\n- tubular_8pin: 8-pin tubular lock, depths 0..9, MACS 8\n  - Standard tubular configuration for bike locks\n  - Used in Kryptonite locks and computer security cables\n- tubular_10pin: 10-pin tubular lock, depths 0..9, MACS 8\n  - Extended pin count for increased security\n  - Rare variant for high-security applications\n- tubular_chicago_7pin: 7-pin Chicago Lock Company style, depths 0..7, MACS 6\n  - Original Chicago Lock \"Ace\" patent design from 1933\n  - 8 depth levels (0-7) standard for vintage tubular locks\n  - Common in older vending machines and coin-operated equipment\n- tubular_ace_8pin: 8-pin Ace-style tubular lock, depths 0..7, MACS 6\n  - 8-pin variant of Chicago Lock design\n  - Standard configuration for mid-security applications\n  - Widely used in laundromat equipment and arcade machines\n\nWafer Tumbler Locks\n- wafer_5wafer_shallow: 5-wafer lock, depths 0..4, MACS 3\n  - Common desk drawer and cabinet lock\n  - Shallow depth range for simple applications\n  - Reference: https://en.wikipedia.org/wiki/Wafer_tumbler_lock\n- wafer_5wafer_deep: 5-wafer lock, depths 0..7, MACS 6\n  - Deeper cuts for increased security\n  - Used in better quality furniture locks\n- wafer_6wafer_auto: 6-wafer automotive lock, depths 0..5, MACS 4\n  - Typical automotive wafer configuration\n  - Historical use in vehicle ignitions and doors (pre-1960s to 1980s)\n- wafer_10wafer_double: 10-wafer double-sided lock, depths 0..9, MACS 8\n  - Advanced wafer configuration with opposed wafer sets\n  - Double-bitted key for higher security applications\n- wafer_gm_sidebar_10: 10-wafer GM sidebar lock, depths 0..9, MACS 8\n  - General Motors sidebar wafer tumbler system\n  - Used in GM vehicles from 1960s-1990s\n  - Features sidebar mechanism for additional security\n- wafer_ford_8cut: 8-wafer Ford automotive lock, depths 0..7, MACS 6\n  - Ford Motor Company 8-cut wafer system\n  - Common in Ford vehicles 1960s-1980s\n  - Single-sided key with 8 depth positions\n- wafer_ford_10cut: 10-wafer Ford automotive lock, depths 0..9, MACS 8\n  - Extended Ford wafer system with 10 cuts\n  - Used in later Ford models for increased security\n  - Higher key combination count\n- wafer_chrysler_7cut: 7-wafer Chrysler automotive lock, depths 0..6, MACS 5\n  - Chrysler Corporation 7-cut wafer system\n  - Used in Chrysler, Dodge, Plymouth vehicles\n  - 7 depth positions for mid-level security\n- wafer_chrysler_10cut: 10-wafer Chrysler automotive lock, depths 0..9, MACS 8\n  - Extended Chrysler wafer system with 10 positions\n  - Higher security variant for later model vehicles\n  - Increased key space complexity\n- wafer_desk_drawer_5: 5-wafer desk drawer lock, depths 0..4, MACS 3\n  - Standard office desk drawer configuration\n  - Simple 5-cut system for furniture applications\n  - Very common in office furniture from major manufacturers\n- wafer_cabinet_6: 6-wafer cabinet lock, depths 0..5, MACS 4\n  - Filing cabinet and storage cabinet standard\n  - 6-wafer configuration for light commercial use\n  - Used in metal office cabinets and storage units\n- wafer_mailbox_5: 5-wafer mailbox lock, depths 0..4, MACS 3\n  - USPS and residential mailbox standard wafer lock\n  - Weather-resistant low-security configuration\n  - Simple 5-cut pattern for postal applications\n\nEducational Presets (NO Terminal Invalidity)\n- simple_no_terminal_2depth: 4-position lock, depths 0..1, MACS 1\n  - Minimal lock with 2 depth levels\n  - NO terminal invalidity: any sequence can be made valid\n  - Demonstrates boundary case where depth range equals MACS\n- simple_no_terminal_3depth: 4-position lock, depths 0..2, MACS 2\n  - Simple lock with 3 depth levels\n  - NO terminal invalidity: MACS equals depth range\n  - Educational example showing when terminal invalidity cannot exist\n- simple_no_terminal_equal_macs: 5-position lock, depths 0..5, MACS 5\n  - Lock where MACS equals maximum depth\n  - NO terminal invalidity: any depth transition is acceptable\n  - Illustrates the mathematical condition where terminal invalidity is impossible\n\nCLI\n- Show presets:\n  python3 tool.py presets\n- Check:\n  python3 tool.py check --preset kwikset_6in5 --seq 2,1,1,1,1,1\n- Check with Bellman-Ford solver:\n  python3 tool.py check --preset us --seq 1,7,1,1,1 --use-bellman-ford\n- Repair:\n  python3 tool.py repair --preset us --pins 5 --seq 1,7,1,1,1\n- Repair with Bellman-Ford solver:\n  python3 tool.py repair --preset us --seq 1,7,1,1,1 --use-bellman-ford\n- Generate terminal examples:\n  python3 tool.py list-terminal --preset schlage_everest29_sl_tip --limit 5\n- BEST A2 tip-stop check:\n  python3 tool.py check --preset best_a2_tip --seq 2,1,1,1,1,1,1\n- Yale IC A2 tip-stop check:\n  python3 tool.py check --preset yale_ic_a2_tip --seq 2,1,1,1,1,1,1\n- Yale KeyMark terminal examples:\n  python3 tool.py list-terminal --preset yale_keymark --limit 5\n- ASSA ABLOY Yale terminal examples:\n  python3 tool.py list-terminal --preset assa_abloy_yale --limit 5\n- Warded lock examples:\n  python3 tool.py check --preset warded_binary --seq 1,0,1,0\n  python3 tool.py check --preset warded_lever_6 --seq 0,5,0,3,2\n  python3 tool.py check --preset warded_skeleton_simple --seq 1,0,1\n  python3 tool.py list-terminal --preset warded_padlock_4ward --limit 5\n- Disc tumbler lock examples:\n  python3 tool.py check --preset disc_abloy_classic_6 --seq 0,5,0,3,2,1\n  python3 tool.py check --preset disc_abloy_classic_6 --seq 0,0,0,0,1,2\n  python3 tool.py check --preset disc_abloy_disklock_10 --seq 0,11,5,8,3,7,2,9,4,6\n  python3 tool.py check --preset disc_abloy_exec_6 --seq 0,10,5,7,3,8\n  python3 tool.py check --preset disc_abloy_profile_10 --seq 0,9,4,7,2,6,1,8,3,5\n  python3 tool.py list-terminal --preset disc_abloy_protec_8 --limit 5\n- Tubular lock examples:\n  python3 tool.py check --preset tubular_4pin --seq 0,9,5,3\n  python3 tool.py check --preset tubular_6pin --seq 0,9,4,6,2,7\n  python3 tool.py check --preset tubular_7pin --seq 0,9,0,5,3,2,1\n  python3 tool.py check --preset tubular_chicago_7pin --seq 0,7,3,5,2,4,6\n  python3 tool.py check --preset tubular_ace_8pin --seq 0,7,2,5,1,6,3,4\n  python3 tool.py list-terminal --preset tubular_10pin --limit 5\n- Wafer tumbler lock examples:\n  python3 tool.py check --preset wafer_5wafer_shallow --seq 0,4,0,2,1\n  python3 tool.py check --preset wafer_gm_sidebar_10 --seq 0,9,3,7,1,8,2,6,4,5\n  python3 tool.py check --preset wafer_ford_8cut --seq 0,7,3,5,2,6,1,4\n  python3 tool.py check --preset wafer_chrysler_10cut --seq 0,9,4,7,2,8,3,6,1,5\n  python3 tool.py check --preset wafer_desk_drawer_5 --seq 0,4,2,3,1\n  python3 tool.py list-terminal --preset wafer_cabinet_6 --limit 5\n- Enumerate small spaces:\n  python3 tool.py enumerate --preset euro --pins 4 --max-repeat 4\n\nExamples\n- Kwikset 6→5 case:\n  - Input: 2,1,1,1,1,1\n  - Check: terminal=True reason=forbidden/no-cut station cut present\n- Shoulder stop first-station restriction (if min_first_station_index=1):\n  - Input: 2,1,1,1,1,1\n  - Check: terminal=True reason=first station not allowed for this stop type\n- Station ceiling example (configure --ceilings None,4,None,None,None,None and put 5 at pos 1):\n  - Input: 1,5,1,1,1,1\n  - Check: terminal=True reason=station-specific ceiling violated\n- Abloy Classic consecutive repeat constraint (max_consecutive_repeats=3):\n  - Input: 0,0,0,0,1,2 (4 consecutive 0s)\n  - Check: terminal=True reason=too many consecutive repeats of same cut\n  - Input: 0,0,0,1,2,3 (exactly 3 consecutive 0s)\n  - Check: terminal=False reason=repairable to a valid bitting by deepening\n\nRun locally\n- cd /home/ubuntu/work/key_bittings\n- python3 tool.py presets\n- Use the commands above to verify terminal invalidity under manufacturer constraints.\n\nNotes\n- Euro EN 1303/18252 public summaries are performance-classification oriented and do not include cutting geometry; OEM documents govern practical station/stop constraints.\n- The model accepts future numeric station ceilings when OEM tables are found; examples here are illustrative but the Kwikset no‑cut and Schlage stop rules are directly cited.\n- Abloy Classic enforces a max_consecutive_repeats=3 constraint, meaning no more than 3 consecutive positions can have the same cut. This creates many terminally invalid sequences that cannot be fixed by deepening.\n- Lock types beyond pin tumblers (warded, tubular, wafer) use theoretical models based on general principles where formal specifications are unavailable.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferkinalp%2Finvalid-bitting-generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferkinalp%2Finvalid-bitting-generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferkinalp%2Finvalid-bitting-generator/lists"}