Trentin Davide
4067366d06
fix(mitsubishi): symmetric read/write FTP path (ISS-020)
...
WriteProgramAsync resolved -path as a directory and combined it with
program.Name ("1" + "O0001" -> "1/O0001"), while ReadProgramAsync
resolved it as a program identifier under ProgramDirectory ("1" ->
"/PRG/1"). The write target therefore never matched the read target:
STOR went to a nonexistent relative dir and failed with "unable to
connect to remote server" (-204). Surfaced once ISS-018/019 stopped
masking it.
Per Mitsubishi NC Explorer manual IB-1500904, programs live under
PRG/USER and are addressed by their program name/number with no
extension. Resolve write the same way as read: ResolvePath is now
single-arg (path = identifier or full path, joined with
ProgramDirectory). program.Name is used for validation only.
Update write unit test to the symmetric contract and add a roundtrip
regression test (-path "1" -> /PRG/1).
Siemens/Fagor share the pattern but tie extension handling to name
(entangled with ISS-013); left open in ISS-020.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 09:57:10 +02:00
Trentin Davide
85d0b579aa
fix(validator,field-test): unblock Fanuc/Mitsubishi upload (ISS-018, ISS-019)
...
ISS-018: FanucProgram.Standardize() prepends a leading '\n' to the
program body, so the O#### header is not on lines[0]. The validator
first-line check read lines[0] and always failed "First line must be
O####", rejecting every valid Fanuc/Mitsubishi upload. Scan the first
non-blank line instead. Upload (FOCAS tape) format unchanged.
ISS-019: field-test .bat files passed -pathprogramma unquoted; on
install paths with spaces ("visual studio prove") cmd split the arg and
ArgParser captured only the first token -> truncated path. Quote the
arg in all 7 scripts.
Add regression test Validate_LeadingBlankLineBeforeONumber for both
Fanuc and Mitsubishi.
Surfaced by field testing against a local docker FTP server.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 09:42:46 +02:00
Trentin Davide
3fd3047584
docs(test): add Mitsubishi field-test kit (scripts + criticità checklist)
...
Windows batch harness + extensive IT README for on-site Mitsubishi CNC
testing. Covers connect/invia/scarica/validator/offset/param scenarios.
Documents C1-C8 criticità found in code review:
- path mapping mismatch (download /PRG/<int> vs upload relative <path>/<name>)
- Standardize leading \n may trip validator first-line gate
- hardcoded /PRG/ ProgramDirectory, no CLI override
- Int16 -path limit, ASCII-only FTP, plaintext credentials
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 09:03:10 +02:00
d4a3e7c4f0
chore: add ConfuserEx obfuscator project config
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 22:09:10 +02:00
e608977359
docs: add code review bug analysis report
...
Static analysis findings for nc_program_manager: 8 security criticals
(FTP plaintext, LSV2 cleartext, path traversal, license bypass),
4 functional bugs, 3 NRE risks, 3 resource leaks. See BUG_ANALYSIS.md
for prioritized fix list.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 21:53:03 +02:00
dtrentin
68c5a555f3
chore(paul): close v0.6 Fagor Support milestone, log ISS-012..017
...
PAUL bookkeeping per chiusura milestone v0.6 (Phase 16: 16-01 + 16-02):
- STATE.md — sezione v0.6 + Phase 16-01 + 16-02 fixup post-review.
- ROADMAP.md — Milestone v0.6 + Phase 16 (2 plans).
- paul.json — version 0.6.0, milestone Fagor Support, phase 16
fagor-ftp.
- phases/16-fagor-ftp/ — 16-01-PLAN.md + 16-01-SUMMARY.md (impl
iniziale), 16-02-PLAN.md + 16-02-SUMMARY.md (fix post-review).
- ISSUES.md — ISS-012..ISS-017 derivati da code review v0.6:
- ISS-012: Fagor ReadActiveProgramAsync/SelectMainProgram non impl
- ISS-013: Program.Invia accoppia FanucProgram a tutti i produttori
- ISS-014: ResolvePath null-folder NRE pattern (Siemens/Mitsubishi/Fagor)
- ISS-015: encoding source-file rischio codepage Windows non-UTF8
- ISS-016: WriteProgramAsync validator riceve path se Name null
- ISS-017: FagorFtpClient.Ping swallow senza log
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 20:27:44 +02:00
dtrentin
b3d7402498
feat(16-fagor): Fagor CNC FTP support + validator gating
...
Phase 16 (v0.6 milestone) — supporto Fagor CNC via FTP, riuso pattern
Siemens/Mitsubishi (FtpWebRequest + ASCII).
Modelli supportati: 8060/8065/8070 (FTP nativo), 8055 (con opzione
Ethernet). Modelli 8025-8050 esclusi (solo RS232).
Code:
- Cnc/Fagor/* — FagorConnectionConfig, IFagorFtpClient, FagorFtpClient,
FagorMachine. ProgramExtension configurabile (default .nc),
ProgramDirectory /Users/Prg/.
- Cnc/Models/CncManufacturer.cs — enum + Fagor.
- Cnc/CncMachineFactory.cs — case Fagor, porta default 21.
- Cnc/NcProgramValidator.cs — refactor IsRestrictiveDialect():
block-80/no-tab/no-lowercase/nested-parens/comment-32 ora applicati
solo a Fanuc+Mitsubishi (Heidenhain/Siemens/Fagor esenti). Fagor name
rules: max 24 char, no ñ (escape ñ per safety codepage), stem
alphanumerico + spazi (estensione separata).
- ArgParser.cs — case "fagor".
- Program.cs — help text manufacturer/username/password.
Tests:
- FagorMachineTests — 12 unit (10 mock + 2 validator reale).
- FagorMachineIntegrationTests — 5 stub-based (riusa FtpServerStub) + 1
hardware skip via FAGOR_TEST_IP env var.
- NcProgramValidatorTests — 12 nuovi Fagor (8 + 4 extension coverage), 6
lock Siemens/Heidenhain exemption, 3 esistenti Siemens→Fanuc.
- CncMachineFactoryTests — Create_Fagor_ReturnsFagorMachine.
Docs:
- README.md — sezione "Controller Fagor" italiano: modelli supportati/
non supportati, regole nome, env var test.
Build:
- *.csproj — 4 Compile Include main + 2 test.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 20:27:18 +02:00
dtrentin
60ce1c9d57
feat(15-logging): NLog structured logging — all output through NLog (v0.5 complete)
...
Phase 15 complete (2 plans):
- 15-01: NLog 5.2.8 + nlog.config (rolling file daily/7d + console); logger fields in
FanucMachine, HeidenhainMachine, SiemensMachine, MitsubishiMachine, Lsv2Client, Program.cs;
SetState event handler catches → _log.Warn; cleanup catches annotated; ISS-003/ISS-004 closed
- 15-02: All Console.Write/WriteLine in Program.cs replaced with _log.Info (103 calls);
nlog.config console target layout=${message}, levels=Info only — Warn/Error file-only;
operator console output identical; every interaction now timestamped in log file
Milestone v0.5 Operational Quality complete.
Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-18 23:57:27 +02:00
dtrentin
45ca8f5a47
chore(paul): close ISS-007, update git hash and issues log
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 23:25:21 +02:00
dtrentin
32f68c5ed5
feat(14-test-hardening): env-var hardware test scaffolding + LicenseFile edge cases
...
Phase 14 complete — v0.4 Robustness milestone closed:
- HardwareTestHelper.GetIpOrSkip: Assert.Ignore when HEIDENHAIN/SIEMENS/MITSUBISHI_IP not set (ISS-007)
- Hardware_ConnectAsync_RealMachine [Category("Hardware")] added to all 3 integration test files
- LicenseFileTests: 4 tests covering empty, whitespace, valid base64, nonexistent path
- Validate_EmptyFingerprint_ReturnsFalse: confirms validator safe against empty input (ISS-008 scaffold)
- NcProgramManager.Tests.csproj: <Compile> entries for 2 new files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 23:24:58 +02:00
dtrentin
4cd7715594
fix(robustness): null guard WMI reads, dispose SHA256, abort LSV2 timeout (ISS-001, ISS-005, ISS-006)
...
ISS-001: MachineFingerprint.GetFingerprint() — null-safe WMI property reads
- processorID and SerialNumber accessed with ?. and ?? string.Empty
- prevents NullReferenceException on machines with missing WMI properties
ISS-005: LicenseValidator.Validate() — SHA256CryptoServiceProvider in using block
- disposed on all code paths (success and failure)
ISS-006: Lsv2Client.Connect() — close TcpClient on timeout
- _tcp.Close() called when ConnectAsync.Wait() times out
- aborts pending socket task instead of leaking thread-pool slot
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 23:00:08 +02:00
dtrentin
d95ead59af
chore(paul): create v0.4 Robustness milestone
...
Phases:
- 13: robustness-fixes (ISS-001, ISS-005, ISS-006)
- 14: test-hardening (ISS-007, ISS-008)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:55:07 +02:00
dtrentin
d4bb3419e8
docs(issues): create ISSUES.md from deferred items and codebase concerns
...
11 tracked issues from STATE.md deferred items + CONCERNS.md analysis:
- ISS-001: MachineFingerprint null dereference (High, Quick)
- ISS-002: Blocking async .GetAwaiter().GetResult() (Medium, Medium)
- ISS-003: Silent catch {} blocks (High, Quick-Medium)
- ISS-004: No structured logging framework (Medium, Substantial)
- ISS-005: SHA256 not disposed (Low, Quick)
- ISS-006: LSV2 connect timeout doesn't abort (Medium, Quick)
- ISS-007: Integration tests hardcoded IPs (Medium, Quick-Medium)
- ISS-008: MachineFingerprint untested on real hardware (High, Medium)
- ISS-009: Heidenhain ReadActiveProgram not implemented (Low, Substantial)
- ISS-010: Siemens ReadActiveProgram not implemented (Low, Substantial)
- ISS-011: Obsolete crypto APIs (Low, Quick when upgrading)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:52:35 +02:00
dtrentin
dabcf989d9
docs: map existing codebase
...
- STACK.md - Technologies and dependencies (.NET 4.7.2, NuGet, Costura.Fody)
- ARCHITECTURE.md - Layered CLI with ICncMachine factory pattern
- STRUCTURE.md - Directory layout and where to add new code
- CONVENTIONS.md - C# style, naming, result wrapper pattern
- TESTING.md - NUnit 3 + Moq, stubs, ignored FOCAS tests
- INTEGRATIONS.md - FOCAS, LSV2, FTP, RSA licensing
- CONCERNS.md - Blocking async, silent catch, no logging, Windows-only
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:48:20 +02:00
dtrentin
f55d0b313b
docs(12-docs-cli): complete CLI reference in README — all 16 args + 12 error codes
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:37:58 +02:00
dtrentin
bd17ea46e5
feat(11-refactor): extract ArgParser, fix error handling, remove dead code
...
Phase 11 complete:
- ArgParser.cs: CLI parsing extracted from Program.cs (pure static method)
- Program.cs: no static state; Scarica/Invia take explicit InputArgs param
- Program.cs: try/finally with connected flag — fixes connection leak on exception
- Program.cs: PrintErrors helper surfaces CncResult.Errors on every failure
- AesCrypt.cs: deleted (dead code, zero references)
- NcProgramManager.csproj: AesCrypt.cs → ArgParser.cs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 00:01:32 +02:00
dtrentin
718c3ce8da
docs(10-readme-docs): Italian README for NcProgramManager
...
Operator-facing README covering CLI args, license setup, supported
controllers, and NC validation. PAUL phase 10 complete.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 23:46:50 +02:00
dtrentin
15644cfdf8
feat(09-license-generator): standalone LicenseGenerator tool + real RSA key pair
...
Phase 09 complete — v0.2 NcProgramManager milestone done:
- LicenseGenerator standalone console EXE (separate repo: license-generator.git)
- keygen: RSA 2048-bit key pair generation
- fingerprint: WMI machine fingerprint (Windows)
- sign: RSA-SHA256 sign fingerprint -> .lic file
- LicenseValidator.cs: PublicKeyXml PLACEHOLDER replaced with real vendor public key
- Offline license system now production-ready end-to-end
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 23:37:49 +02:00
dtrentin
3312a57757
feat(08-license-integration): wire RSA license check, remove -chiave arg
...
Replace AES checkLicense with MachineFingerprint+LicenseFile+LicenseValidator.
License.lic hardcoded next to EXE; -chiave= CLI arg and InputArgs.chiave removed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 23:10:05 +02:00
dtrentin
39a9566858
feat(07-license-core): RSA offline license core
...
Phase 07 complete:
- IMachineFingerprint + ILicenseValidator interfaces
- MachineFingerprint: WMI CPU ProcessorID + BaseBoard SerialNumber
- LicenseValidator: RSACryptoServiceProvider + SHA256, injectable public key
- LicenseFile.TryRead: out-param bool, no exceptions from file I/O
- 6 NUnit tests (valid/wrong-machine/tampered/empty/not-base64/missing-file)
- 118 tests total, 116 pass, 2 Fanuc FOCAS ignored (Windows DLL)
- Fix: missing 'using System' in CncMachineFactoryTests.cs
- Fix: Dockerfile.test updated for NcProgramManager rename
PublicKeyXml = PLACEHOLDER until Phase 09 generates real key pair.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 22:58:14 +02:00
dtrentin
a5d73db69a
refactor(rename): FanucProgramManager → NcProgramManager
...
Phase 06 complete:
- Namespace renamed in 62 .cs files (namespace + using directives)
- AssemblyName + RootNamespace updated in csproj files
- FanucProgramManager.csproj → NcProgramManager.csproj
- FanucProgramManager.sln → NcProgramManager.sln
- FanucProgramManager.Tests/ → NcProgramManager.Tests/
- FANUCMachine.cs deleted (dead code, zero references)
Fanuc-prefixed class names kept (FanucMachine, FanucProgram,
IFanucMachine) — manufacturer identifiers, not project names.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 22:31:36 +02:00
dtrentin
9bb65c4748
docs(paul): unify phase 5 and close v0.1 milestone
...
Phase 5 (NC Validator) UNIFY complete.
v0.1 Multi-CN Release milestone closed — all 5 phases done.
- 05-01-SUMMARY.md: NcProgramValidator + 30+ tests documented
- ROADMAP.md: all phases marked complete, v0.2 scope drafted
- PROJECT.md: requirements evolved, tech stack updated to 4 manufacturers
- STATE.md: milestone 100%, loop closed, next action documented
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 22:19:50 +02:00
dtrentin
f3f895df82
Initial commit: migrate from FanucProgramManager
2026-05-17 22:10:30 +02:00