From 260d997c27d1fb979ed1d9f1f1c75ff59b1eb76c Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 17:58:03 +0700 Subject: [PATCH 01/69] Add commercial licensing path --- COMMERCIAL-LICENSE.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 COMMERCIAL-LICENSE.md diff --git a/COMMERCIAL-LICENSE.md b/COMMERCIAL-LICENSE.md new file mode 100644 index 0000000..dc47c92 --- /dev/null +++ b/COMMERCIAL-LICENSE.md @@ -0,0 +1,11 @@ +# Commercial Licensing + +ARSVIN is publicly available under the GNU General Public License v3.0 or later (`GPL-3.0-or-later`). + +A separate negotiated commercial license is available for organizations that need proprietary or closed-source integration, OEM or white-label distribution, redistribution outside GPL obligations for a combined proprietary product, private product branches, warranty, maintenance, priority support, training, or engineering services. + +This document is an invitation to discuss commercial terms. It is not itself a commercial license and grants no additional rights. + +Contact the project owner through the `masarray` GitHub profile. Do not post confidential commercial, customer, station, network, SCL, COMTRADE, or packet-capture information in a public issue. + +Commercial licensing can cover only rights controlled by the relevant copyright holder. Historical revisions and third-party components remain subject to their applicable licenses and notices. \ No newline at end of file From 26103825cbe7485f8d9437c0174b5ccb2b1bdfa3 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 17:58:15 +0700 Subject: [PATCH 02/69] Document ARSVIN copyright identity --- COPYRIGHT.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 COPYRIGHT.md diff --git a/COPYRIGHT.md b/COPYRIGHT.md new file mode 100644 index 0000000..ee1a866 --- /dev/null +++ b/COPYRIGHT.md @@ -0,0 +1,9 @@ +# Copyright + +Copyright (C) 2026 Ari Sulistiono. + +GitHub account: `masarray`. + +Copyright ownership applies only to material for which the named copyright holder controls the relevant rights. Third-party components, contributor-owned material, historical grants, generated notices, and external standards remain subject to their own ownership and license terms. + +Repository authorship or account attribution is evidence of activity, not by itself conclusive proof of legal ownership. Employment, invention-assignment, confidentiality, customer, equipment-use, and similar obligations must be reviewed separately where applicable. \ No newline at end of file From 2b775664ae96c7404ebbe773931e834dd45e6816 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 17:58:28 +0700 Subject: [PATCH 03/69] Add trademark and branding policy --- TRADEMARK.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 TRADEMARK.md diff --git a/TRADEMARK.md b/TRADEMARK.md new file mode 100644 index 0000000..5ba0b11 --- /dev/null +++ b/TRADEMARK.md @@ -0,0 +1,14 @@ +# Trademark and Branding Policy + +The software license does not grant rights to use ARSVIN, ArSubsv, project logos, application icons, artwork, or official-release branding in a way that suggests official origin, sponsorship, certification, partnership, or endorsement. + +Except where permitted by applicable law, written permission is required to: + +- market a modified build as an official ARSVIN or ArSubsv release; +- use project logos or icons as the primary identity of another product; +- represent a fork, service, appliance, test set, or training package as approved or certified by the project; or +- use the branding in OEM, white-label, or commercial redistribution. + +Accurate nominative references such as “based on ARSVIN” may be used when they are not misleading, preserve required notices, and clearly distinguish the modified product from official releases. + +No statement in this policy claims that a listed name or mark is registered in every jurisdiction. Trademark availability and registration status require separate clearance. \ No newline at end of file From 29c5f93a6b99aec9228f927387800e246aee7e98 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 17:58:43 +0700 Subject: [PATCH 04/69] Add contributor license agreement --- CONTRIBUTOR-LICENSE-AGREEMENT.md | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 CONTRIBUTOR-LICENSE-AGREEMENT.md diff --git a/CONTRIBUTOR-LICENSE-AGREEMENT.md b/CONTRIBUTOR-LICENSE-AGREEMENT.md new file mode 100644 index 0000000..2b7e63e --- /dev/null +++ b/CONTRIBUTOR-LICENSE-AGREEMENT.md @@ -0,0 +1,48 @@ +# Contributor License Agreement + +**Effective date:** 2026-07-14 +**Repository:** `masarray/arsvin` +**License recipient:** Ari Sulistiono, GitHub account `masarray` (the “Maintainer”) + +This agreement applies to each contribution submitted to this repository on or after the effective date. + +## Contribution + +“Contribution” means source code, documentation, tests, fixtures, diagrams, or other copyrightable material intentionally submitted for inclusion in the repository through a pull request, commit, issue attachment, or another channel expressly accepted by the Maintainer. + +## Contributor representations + +By submitting a Contribution and affirmatively agreeing to this agreement in the pull request, the contributor represents that: + +1. they are legally entitled to submit the Contribution; +2. when the Contribution is created within employment or for an organization, they have authority to grant the rights below; +3. the Contribution does not knowingly contain confidential, customer-owned, employer-owned, unlawfully copied, or undisclosed third-party material; and +4. any included third-party material is clearly identified together with its license and provenance. + +## Copyright license + +The contributor retains ownership of the Contribution and grants the Maintainer a worldwide, non-exclusive, royalty-free, perpetual, irrevocable copyright license to use, reproduce, modify, prepare derivative works of, publicly display, publicly perform, sublicense, relicense, and distribute the Contribution, in source or object form: + +- under GPL-compatible open-source terms; and +- under separate commercial terms. + +The commercial relicensing right applies only to rights actually granted by the contributor. Third-party material remains subject to its own license. + +## Patent license + +The contributor grants the Maintainer and recipients of the project a worldwide, non-exclusive, royalty-free, perpetual, irrevocable patent license under patent claims controlled by the contributor that are necessarily infringed by the Contribution alone or by its combination with the project as submitted. + +## No warranty + +The Contribution is provided without warranty unless separately agreed in writing. + +## Acceptance record + +Agreement is recorded when the contributor: + +1. checks the CLA affirmation in the pull-request template or writes an equivalent affirmative statement in the pull-request discussion; and +2. submits commits carrying the required Developer Certificate of Origin sign-off. + +The public pull-request record and Git commit history are retained as evidence of acceptance and provenance. + +Organizations that require a separately signed agreement should contact the Maintainer before submitting code. \ No newline at end of file From db3e2e28a2c59943ee99dcbe5d01f1b8166e52ed Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 17:58:53 +0700 Subject: [PATCH 05/69] Add Developer Certificate of Origin --- DCO.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 DCO.txt diff --git a/DCO.txt b/DCO.txt new file mode 100644 index 0000000..61b43f8 --- /dev/null +++ b/DCO.txt @@ -0,0 +1,18 @@ +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or + +(b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or + +(c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. + +(d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. \ No newline at end of file From 1d441d97e1478d20f85370b11229439513227f4a Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 17:59:09 +0700 Subject: [PATCH 06/69] Document GPL and historical Apache boundary --- docs/LICENSING.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 docs/LICENSING.md diff --git a/docs/LICENSING.md b/docs/LICENSING.md new file mode 100644 index 0000000..82a5410 --- /dev/null +++ b/docs/LICENSING.md @@ -0,0 +1,45 @@ +# ARSVIN Licensing + +## Current community edition + +The current `main` branch and public release packages produced from revisions after `9440f08b6909ef2dc93dd483cfdcb4e1e86077d0` are licensed under the GNU General Public License v3.0 or later (`GPL-3.0-or-later`). The authoritative license text is the root [LICENSE](../LICENSE) file. + +The GPL applies to the ARSVIN project material covered by that license. Third-party components remain subject to their own licenses and notices. + +## Historical Apache-2.0 revisions + +Revisions up to and including commit: + +```text +9440f08b6909ef2dc93dd483cfdcb4e1e86077d0 +``` + +were released under Apache-2.0 and remain available on branch: + +```text +archive/apache-2.0-final +``` + +Those historical grants remain effective for those earlier revisions. They do not make later changes or current release packages available under Apache-2.0. + +The current branch intentionally does not carry a second Apache license file because current releases are not offered as an Apache-or-GPL choice. + +## Commercial licensing + +A separate negotiated commercial license may be available for proprietary integration, OEM or white-label distribution, closed-source redistribution, private branches, warranty, support, training, and engineering services. See [COMMERCIAL-LICENSE.md](../COMMERCIAL-LICENSE.md). + +`COMMERCIAL-LICENSE.md` is an invitation to discuss terms. It is not itself an executed commercial license and grants no additional rights. + +Commercial terms can cover only rights controlled by the relevant copyright holder. Historical grants, contributor-owned material, standards, and third-party dependencies remain subject to their applicable rights and notices. + +## Contributions + +Contributions submitted after 2026-07-14 require: + +- affirmative acceptance of the [Contributor License Agreement](../CONTRIBUTOR-LICENSE-AGREEMENT.md); +- a Developer Certificate of Origin sign-off on every commit; and +- documented provenance and any required employer or organizational authorization. + +## Branding + +Software-license permissions do not automatically grant project names, logos, icons, artwork, or official-release branding. See [TRADEMARK.md](../TRADEMARK.md). \ No newline at end of file From 87561154c886b32441a12a89f68d0865e3fff9a2 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 17:59:32 +0700 Subject: [PATCH 07/69] Add external IP and provenance review --- ...NAL_IP_AND_PROVENANCE_REVIEW_2026-07-14.md | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 docs/EXTERNAL_IP_AND_PROVENANCE_REVIEW_2026-07-14.md diff --git a/docs/EXTERNAL_IP_AND_PROVENANCE_REVIEW_2026-07-14.md b/docs/EXTERNAL_IP_AND_PROVENANCE_REVIEW_2026-07-14.md new file mode 100644 index 0000000..3e3f27e --- /dev/null +++ b/docs/EXTERNAL_IP_AND_PROVENANCE_REVIEW_2026-07-14.md @@ -0,0 +1,66 @@ +# External IP and Provenance Review — 2026-07-14 + +This is a repository-evidence and process review. It is not a legal opinion and cannot establish every off-repository fact or contractual obligation. + +## Scope + +The review covers the current ARSVIN repository, Publisher and Subscriber applications, shared engine, tests, samples, release automation, documentation, website, screenshots, and public claims. + +## Repository evidence + +At the review date, the tracked project presents ARSVIN as an independently developed IEC 61850 Sampled Values engineering suite. The current source uses project-owned architecture and application assets together with separately identified dependencies listed in `THIRD_PARTY_NOTICES.md`. + +Repository inspection can identify tracked source, dependencies, notices, assets, wording, and contribution records. It cannot prove the absence of undisclosed private material, establish employer ownership, or resolve invention-assignment, confidentiality, customer, equipment-use, or working-time obligations. + +Git account and commit attribution identify repository activity; they are not by themselves conclusive proof of legal ownership. + +## External implementation boundary + +External software may be used only as a lawfully licensed black-box interoperability endpoint within the applicable license, organizational policy, and authorization boundary. + +The following must not be used as ARSVIN implementation design material unless the project has documented redistribution and relicensing rights: + +- external source code or generated bindings; +- API composition, internal structure, tests, examples, or naming schemes; +- copied documentation wording, report templates, screenshots, UI composition, icons, or artwork; +- extracted binaries, resources, databases, manuals, or help content; and +- confidential customer, employer, laboratory, or station material. + +Observed behavior must be reduced to neutral protocol facts and independently implemented and tested. + +## Fixtures and evidence + +Public fixtures should be synthetic or contributor-owned. A real SCL, COMTRADE, PCAP, screenshot, or diagnostic sample requires documented authority to share, sanitization, and a clear provenance record. + +Do not publish credentials, customer or employer identifiers, station names, restricted addressing, production network plans, private support material, or captures whose redistribution rights are uncertain. + +## Licensing transition + +The historical Apache-2.0 boundary is commit `9440f08b6909ef2dc93dd483cfdcb4e1e86077d0`, retained on `archive/apache-2.0-final`. Later community revisions are offered under `GPL-3.0-or-later`. + +A separate commercial path may cover only rights controlled by the relevant copyright holder. Third-party and historical material remains subject to its applicable license. + +## Controls + +- current-license and public-wording verification in CI; +- dependency locking and third-party notices; +- CLA plus DCO for future contributions; +- sanitized issue and pull-request evidence requirements; +- explicit operational and conformance claim boundaries; +- immutable tagged releases and reproducible release evidence; and +- manual review before high-value OEM, white-label, or proprietary distribution. + +## Remaining manual checks + +Before a significant commercial agreement, review: + +- the contributor and copyright chain for the exact revision being licensed; +- employment, invention-assignment, confidentiality, and customer obligations; +- every private SCL, COMTRADE, PCAP, screenshot, design note, and test artifact used during development; +- third-party package and tool terms for the planned distribution model; +- trademark clearance and visual-similarity risk; and +- the exact source, binary, installer, SBOM, and notices delivered to the customer. + +## Conclusion + +The repository controls support a defensible independent-development and dual-channel licensing process. They reduce, but do not eliminate, copyright, license, trademark, confidentiality, contractual, or ownership risk. \ No newline at end of file From 2a825ac6f4cd664c9fedd457cf5f44f80c2351fe Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 17:59:53 +0700 Subject: [PATCH 08/69] Add public wording and claim review --- docs/WORDING_AND_CLAIM_REVIEW_2026-07-14.md | 61 +++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 docs/WORDING_AND_CLAIM_REVIEW_2026-07-14.md diff --git a/docs/WORDING_AND_CLAIM_REVIEW_2026-07-14.md b/docs/WORDING_AND_CLAIM_REVIEW_2026-07-14.md new file mode 100644 index 0000000..76a0f00 --- /dev/null +++ b/docs/WORDING_AND_CLAIM_REVIEW_2026-07-14.md @@ -0,0 +1,61 @@ +# Public Wording and Claim Review — 2026-07-14 + +This review defines the wording used in the README, documentation, landing pages, release notes, installer, and issue templates. + +## Approved positioning + +ARSVIN is a Windows IEC 61850 Sampled Values engineering suite for authorized laboratory, development, FAT/SAT preparation, troubleshooting, education, and commissioning-support workflows. + +The Publisher generates streams and records transmitter-side evidence. ArSubsv receives, decodes, visualizes, and records receiver-side evidence from the selected computer and network adapter. + +## Evidence boundary + +Public wording must distinguish: + +- configured SCL expectations from observed Ethernet traffic; +- transmitter evidence from receiver evidence; +- software observations from protection-system behavior; +- test or laboratory evidence from formal conformance; and +- protocol readiness from network authorization and operational authority. + +ARSVIN cannot infer application-layer acknowledgement for multicast Sampled Values and does not prove that another IED consumed, trusted, or acted on a stream. + +## Terms to avoid as unqualified claims + +Avoid unqualified use of: + +- certified, compliant, conformant, universal, deterministic, calibrated, production-ready; +- safe, secure, trusted, correct, guaranteed, field-proven; +- official, approved, endorsed, or equivalent; and +- wording that implies protection performance, functional safety, cybersecurity approval, switching authority, or equipment isolation. + +Use scoped evidence terms instead, such as: + +- implemented; +- covered by deterministic tests; +- validated by the stated automated check; +- exercised in a simulator, loopback, or identified laboratory environment; +- observed by the selected computer and adapter; +- provisional, partial, unsupported, unknown, or not yet verified. + +## Operational wording + +Prefer “guarded live workflow” or “authorized isolated test link” over “safe live mode.” Software checks cannot establish site safety, isolation, authorization, or the absence of process consequences. + +Raw Ethernet transmission and capture must be described as active network operations requiring explicit authorization and an appropriate test boundary. + +## External products and comparisons + +Public documentation should describe required engineering outcomes directly. It must not use unrelated product branding as a feature target, imply affiliation, or copy another product’s UI, wording, reports, screenshots, artwork, internal structure, or documentation. + +Lawfully licensed black-box interoperability testing may support neutral protocol observations. It does not authorize copying protected expression or internal implementation material. + +## Licensing wording + +Current public source and release packages are `GPL-3.0-or-later`. Historical Apache-2.0 revisions are identified only as history and remain on `archive/apache-2.0-final`. The two licenses must not be presented as a current user choice. + +Commercial licensing is a separate negotiated path. A repository notice inviting commercial discussion is not itself a commercial license. + +## Review result + +The licensing migration updates public metadata, structured data, README, generated documentation, release packages, installer content, project metadata, contribution records, and automated checks to follow these boundaries. \ No newline at end of file From 56d0e8017be988bdb473121d9c589b2b2cc04845 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:02:19 +0700 Subject: [PATCH 09/69] Relicense current ARSVIN main under GPL-3.0-or-later --- LICENSE | 876 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 674 insertions(+), 202 deletions(-) diff --git a/LICENSE b/LICENSE index d645695..0cf3c95 100644 --- a/LICENSE +++ b/LICENSE @@ -1,202 +1,674 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided +you inform other peers where the object code and Corresponding +Source of the work are being offered to the general public at no +charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying a +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file From 844a3652949a88f0469657e2b95685fc14ca68a3 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:02:45 +0700 Subject: [PATCH 10/69] Clarify current GPL and historical licensing boundary --- NOTICE | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/NOTICE b/NOTICE index 1c4c2b6..610671c 100644 --- a/NOTICE +++ b/NOTICE @@ -1,12 +1,18 @@ ARSVIN - IEC 61850 Sampled Values Engineering Suite -Copyright 2026 Ari Sulistiono +Copyright (C) 2026 Ari Sulistiono -Licensed under the Apache License, Version 2.0. +Current community source and current public release packages are licensed under the GNU General Public License v3.0 or later (GPL-3.0-or-later). + +A separate negotiated commercial license may be available. COMMERCIAL-LICENSE.md is an invitation to discuss terms and does not itself grant additional rights. + +Revisions up to and including commit 9440f08b6909ef2dc93dd483cfdcb4e1e86077d0 were released under Apache-2.0 and remain available on archive/apache-2.0-final. Those historical grants apply only to those earlier revisions. Author: Ari Sulistiono GitHub: https://github.com/masarray Project: https://github.com/masarray/arsvin -ARSVIN includes a Sampled Values Publisher and the ArSubsv Subscriber companion. The software can capture and transmit raw Ethernet frames and is intended only for isolated laboratory networks, authorized point-to-point engineering tests, development, troubleshooting support, and education. +ARSVIN includes a Sampled Values Publisher and the ArSubsv Subscriber companion. The software can capture and transmit raw Ethernet frames and is intended for authorized laboratory networks, point-to-point engineering tests, development, troubleshooting support, commissioning preparation, and education. + +ARSVIN is not a certified IEC 61850 conformance tool, calibrated merging unit, protection test set, deterministic real-time platform, functional-safety system, cybersecurity-certified product, or production process-bus monitoring system. -ARSVIN is not a certified IEC 61850 conformance tool, calibrated merging unit, protection test set, deterministic real-time platform, or production process-bus monitoring system. +Third-party components remain subject to the licenses and notices identified in THIRD_PARTY_NOTICES.md. Project branding is governed separately by TRADEMARK.md. \ No newline at end of file From 9e454073a0d0f072a2a1772d336a1e5611e37500 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:02:56 +0700 Subject: [PATCH 11/69] Set current package license to GPL-3.0-or-later --- Directory.Build.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 0ddc068..b562075 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -11,9 +11,9 @@ 0.4.0 https://github.com/masarray/arsvin git - Apache-2.0 + GPL-3.0-or-later Ari Sulistiono Ari Sulistiono Copyright © 2026 Ari Sulistiono - + \ No newline at end of file From 22ed6f688f171add9101c1b09dddcfbd545150a5 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:03:47 +0700 Subject: [PATCH 12/69] Rebuild README for GPL community and commercial licensing --- README.md | 242 +++++++++++++++++++++++++++++------------------------- 1 file changed, 132 insertions(+), 110 deletions(-) diff --git a/README.md b/README.md index 9b7c745..bcde65a 100644 --- a/README.md +++ b/README.md @@ -1,107 +1,153 @@ -# ARSVIN — Open-Source IEC 61850 Sampled Values Workbench for Windows +
+ +# ARSVIN + +### IEC 61850 Sampled Values Publisher, Subscriber & Evidence Workbench for Windows + +**SCL-driven stream generation, COMTRADE replay, live and PCAP analysis, waveform, phasor, RMS, continuity diagnostics, and repeatable engineering evidence.** [![CI](https://github.com/masarray/arsvin/actions/workflows/ci.yml/badge.svg)](https://github.com/masarray/arsvin/actions/workflows/ci.yml) [![Release](https://github.com/masarray/arsvin/actions/workflows/release.yml/badge.svg)](https://github.com/masarray/arsvin/actions/workflows/release.yml) [![CodeQL](https://github.com/masarray/arsvin/actions/workflows/codeql.yml/badge.svg)](https://github.com/masarray/arsvin/actions/workflows/codeql.yml) -[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) +[![License](https://img.shields.io/badge/license-GPL--3.0--or--later-2563eb.svg)](LICENSE) [![Platform](https://img.shields.io/badge/platform-Windows%2010%2F11-0078D4.svg)](#system-requirements) [![.NET](https://img.shields.io/badge/.NET-8.0-512BD4.svg)](#build-from-source) -**ARSVIN** is a focused, Apache-2.0 engineering suite for IEC 61850 Sampled Values on Windows. It combines an SCL-driven **SV Publisher** with **ArSubsv**, a live/PCAP **SV Subscriber and analysis companion** for transparent, repeatable laboratory workflows. +[**Download**](https://github.com/masarray/arsvin/releases/latest) · [**Product site**](https://masarray.github.io/arsvin/) · [**Quick start**](docs/quick-start.md) · [**Documentation**](docs/index.md) · [**Licensing**](docs/LICENSING.md) -

- ARSVIN Publisher SV Setup interface with SCL stream selection, network parameters, source modes, and manual output controls -

+

- Download · - Product site · - Quick start · - Documentation · - Contribute + ARSVIN Publisher Sampled Values setup with SCL stream selection, source modes, network settings, and manual output controls

> [!CAUTION] -> ARSVIN can capture and transmit raw Ethernet traffic. Use it only on isolated laboratory networks, point-to-point test links, or networks where you have explicit authorization. It is not a certified relay test set, calibrated merging unit, protection trip-time platform, production process-bus monitor, or IEC 61850 conformance tool. +> ARSVIN can capture and transmit raw Ethernet traffic. Use live features only on an isolated laboratory network, an authorized point-to-point test link, or another network for which you have explicit authority. ARSVIN is not a certified relay test set, calibrated merging unit, deterministic real-time platform, functional-safety system, production process-bus monitor, or IEC 61850 conformance certificate. + +## Engineering purpose + +ARSVIN is a focused Windows suite for practical IEC 61850 Sampled Values work. It combines: + +- **ARSVIN Publisher** for SCL-assisted stream configuration, manual and scenario-based generation, waveform shaping, COMTRADE replay, timing-health visibility, and transmitter-side evidence; and +- **ArSubsv Subscriber** for live or PCAP stream discovery, decoding, SCL-assisted binding, waveform, phasor, RMS, continuity diagnostics, and receiver-side evidence. + +Publisher evidence shows what the selected computer generated. Subscriber evidence shows what the selected computer and network adapter received and decoded. Neither proves that another IED consumed, trusted, or acted on a multicast stream. ## Real application views | ArSubsv stream monitor | ArSubsv live analysis | |---|---| -| ArSubsv stream monitor with voltage and current waveforms, phasor view, RMS values, and discovered Sampled Values streams | ArSubsv live analysis workspace with channel table, phasor display, voltage waveform, and current waveform | +| ArSubsv stream monitor with discovered Sampled Values streams, voltage and current waveforms, phasor view, and RMS values | ArSubsv live analysis workspace with channel table, phasor display, voltage waveform, and current waveform | -The screenshots above are captured from the actual Windows applications. They show the Publisher setup workflow and the Subscriber waveform, phasor, channel, RMS, and stream-analysis views. +These screenshots are captured from the project applications. Public artwork and interface assets are maintained under the project’s own branding and provenance controls. -## Two focused applications +## Core workflows -| Application | Purpose | Typical workflow | -|---|---|---| -| **ARSVIN Publisher** | Generate IEC 61850 Sampled Values from SCL settings, manual values, scenarios, or COMTRADE records. | Configure → preflight → dry run/live TX → export PCAP and report. | -| **ArSubsv Subscriber** | Discover, receive, decode, visualize, and assess SV streams from a live Npcap adapter or PCAP file. | Capture/import → bind to SCL → inspect values, waveform, phasor, RMS, and stream health → export report. | +### Publisher -The tools are intentionally separated. Publisher evidence proves what the PC generated; Subscriber evidence proves what the selected PC/NIC received and decoded. Neither alone proves that a protection IED consumed the multicast stream. +```text +Open or create configuration + ↓ +Review SCL-derived stream and dataset settings + ↓ +Select manual, scenario, waveform, or COMTRADE source + ↓ +Run preflight and dry-run checks + ↓ +Transmit only on an authorized test link + ↓ +Export PCAP, timing health, and Markdown evidence +``` -## Key capabilities +### Subscriber -### Publisher +```text +Choose live adapter or PCAP file + ↓ +Discover Sampled Values streams + ↓ +Optionally bind observed traffic to SCL expectations + ↓ +Inspect counters, timing, decoded values, waveform, phasor, and RMS + ↓ +Record mismatches and receiver-side evidence +``` + +## Current capabilities + +### ARSVIN Publisher - SCL/SCD stream setup for APPID, destination MAC, VLAN, `svID`, dataset, `confRev`, `smpRate`, `smpMod`, and `nofASDU`. -- Lab-oriented IEC 61850-9-2LE-style 4I+4V publishing. -- Multi-ASDU frame packing with `nofASDU=1/2/4/8`. +- Laboratory-oriented IEC 61850-9-2LE-style 4I+4V publishing. +- Multi-ASDU packing with `nofASDU=1/2/4/8`. - Up to three independent publisher slots. - Manual values, ramps, state sequences, per-phase scenarios, waveform shaping, and COMTRADE replay. - Intentional quality-bit modes for controlled behavior checks. -- TX timing health: target/actual FPS, jitter, late frames, missed schedules, and send duration. -- Generated PCAP and Markdown evidence reports. +- Target/actual frame rate, jitter, late-frame, missed-schedule, and send-duration evidence. +- Generated PCAP and Markdown reports. -### Subscriber / ArSubsv +### ArSubsv Subscriber -- Live SV capture through Npcap and offline classic-PCAP import. +- Live capture through Npcap and offline classic-PCAP import. - Stream discovery and SCL-assisted binding. - APPID, VLAN, `svID`, `confRev`, `nofASDU`, sample-rate, and payload-layout checks. - `smpCnt` continuity and stream-health diagnostics. - Decoded instantaneous values, oscilloscope waveform, phasor, and RMS views. - Receiver-side Markdown evidence reports. -- Shared-engine foundation for evidence-aware profile classification and configuration-versus-wire comparison; live UI integration remains a following milestone. +- Shared-engine foundation for evidence-aware profile classification and configuration-versus-wire comparison. -## Profile intelligence foundation +## Evidence-aware profile foundation -The shared engine now separates: +The engine separates: ```text Observed wire facts Configured SCL expectations Evidence-backed profile definitions -Explainable profile confidence +Explainable confidence Strict or compatible mismatch findings ``` -Sparse evidence cannot produce a false `Confirmed` result. Unknown or conflicting receive traffic remains observable, and the built-in catalog contains only a generic SCL-driven Layer-2 fallback until named-profile requirements are verified. +Sparse evidence does not produce a `Confirmed` profile result. Unknown or conflicting traffic remains visible. Named-profile support is added only when requirements and test evidence have documented provenance. + +See [SV Profile Infrastructure](docs/sv-profile-infrastructure.md), [Profile Detection Output Contract](docs/profile-detection-output.md), and [SV Standards and Evidence Research Gate](docs/sv-research-gate.md). + +## Supported scope and claim boundary + +| Area | Current status | Boundary | +|---|---|---| +| IEC 61850 Sampled Values APDU | Publisher and Subscriber implementation for engineering and laboratory use | Not certified conformance testing. | +| IEC 61850-9-2LE-style 4I+4V | Implemented laboratory workflow | Formal profile verification and broader device evidence remain pending. | +| Generic SCL-driven Layer-2 SV | Dataset-aware engine foundation | Unknown layouts remain visible and unsupported elements are diagnosed. | +| Evidence-aware profile detection | Engine infrastructure implemented | Named-profile definitions require verified source and device evidence. | +| `nofASDU` | UI workflows emphasize `1`, `2`, `4`, and `8` | Software and PC timing remain non-deterministic. | +| COMTRADE | ASCII, BINARY, BINARY32, and FLOAT32 analog replay | Scaling and channel mapping must be reviewed before live transmission. | +| PTP / `smpSynch` | Compatibility-oriented laboratory behavior | Not an IEC 61850-9-3 certified clock. | +| Windows timing | Best-effort scheduling with visible health metrics | Not deterministic real-time execution. | +| IED subscription proof | Not provided | Sampled Values multicast has no application-layer acknowledgement. | -See [SV Profile Infrastructure](docs/sv-profile-infrastructure.md) and [SV Standards and Evidence Research Gate](docs/sv-research-gate.md). +Evidence language in this repository distinguishes implemented behavior, deterministic tests, simulator or loopback evidence, laboratory observations, and features that remain provisional or unverified. ## Release downloads -Every tagged release builds validated Windows x64 artifacts with stable filenames: +Every tagged release builds Windows x64 artifacts with stable filenames: -| Artifact | Use | +| Artifact | Purpose | |---|---| -| `ARSVIN-Publisher-win-x64.exe` | Self-contained, single-file portable Publisher. | -| `ArSubsv-Subscriber-win-x64.exe` | Self-contained, single-file portable Subscriber. | -| `ARSVIN-Suite-Setup-win-x64.exe` | Installer containing both applications, Start Menu shortcuts, documentation, and uninstaller. | -| `ARSVIN-win-x64-portable.zip` | Portable suite folder containing both applications and essential documentation. | -| `ARSVIN-SBOM.cdx.json` | CycloneDX 1.5 software bill of materials for resolved NuGet dependencies. | +| `ARSVIN-Publisher-win-x64.exe` | Self-contained single-file Publisher. | +| `ArSubsv-Subscriber-win-x64.exe` | Self-contained single-file Subscriber. | +| `ARSVIN-Suite-Setup-win-x64.exe` | Installer containing both applications, documentation, notices, and uninstaller. | +| `ARSVIN-win-x64-portable.zip` | Portable suite with both applications and required legal/documentation files. | +| `ARSVIN-SBOM.cdx.json` | CycloneDX 1.5 software bill of materials. | | `SHA256SUMS.txt` | SHA-256 checksums for release verification. | -Stable and prerelease tag builds publish signed GitHub artifact attestations for provenance. Verify a downloaded file with GitHub CLI: +Tagged releases publish GitHub artifact attestations. Example verification: ```powershell gh attestation verify .\ARSVIN-Suite-Setup-win-x64.exe --repo masarray/arsvin ``` -Published GitHub Releases are immutable in the automated workflow. Corrections use a new semantic-version tag instead of replacing existing assets. - -The binaries are currently **unsigned**. Windows SmartScreen may show an unknown-publisher warning. Releases do not silently install Npcap; download Npcap from its official website when live capture or transmission is required. +The binaries are currently unsigned, so Windows SmartScreen may display an unknown-publisher warning. Npcap is not silently installed or bundled; install it separately from its official source when live capture or transmission is required. ## Quick start @@ -109,31 +155,17 @@ The binaries are currently **unsigned**. Windows SmartScreen may show an unknown 1. Download `ARSVIN-Suite-Setup-win-x64.exe` from the latest release. 2. Install the suite. -3. Install Npcap separately for live Ethernet capture/transmission. -4. Open **ARSVIN Publisher** or **ArSubsv Subscriber** from the Start Menu. -5. Start with a dry run, sample file, PCAP import, or isolated point-to-point link. +3. Install Npcap separately for live Ethernet workflows. +4. Open **ARSVIN Publisher** or **ArSubsv Subscriber**. +5. Begin with a dry run, synthetic sample, PCAP import, or authorized isolated test link. ### Portable -1. Download the Publisher or Subscriber portable `.exe`. +1. Download the portable Publisher, Subscriber, or suite ZIP. 2. Run the selected application directly. -3. Run as Administrator only when the selected Npcap/live-network workflow requires it. - -See [Quick Start](docs/quick-start.md) and [Build and Release](docs/build-and-release.md). +3. Use elevated privileges only when required by the selected Npcap and network configuration. -## Supported scope - -| Area | Current status | Boundary | -|---|---|---| -| IEC 61850 Sampled Values APDU | Publisher and Subscriber implementation for engineering/lab use | Not certified conformance testing. | -| IEC 61850-9-2LE-style 4I+4V | Implemented laboratory workflow | Formal profile verification and broader device evidence remain pending. | -| Generic SCL-driven Layer-2 SV | Dataset-aware engine foundation | Unknown layouts remain visible; unsupported payload elements are diagnosed. | -| Evidence-aware profile detection | Engine infrastructure implemented | Named-profile definitions await verified source and device evidence. | -| `nofASDU` | UI workflows emphasize `1`, `2`, `4`, `8` | Publisher and receiver behavior is software/PC timing dependent. | -| COMTRADE | ASCII, BINARY, BINARY32, FLOAT32 analog replay | Verify scaling and channel mapping before live TX. | -| PTP / `smpSynch` | Compatibility and lab behavior | Not an IEC 61850-9-3 certified clock. | -| Windows timing | Best-effort scheduling with visible health metrics | Not deterministic real-time execution. | -| IED subscription proof | Not provided | SV multicast has no application-layer acknowledgement. | +See [Quick Start](docs/quick-start.md), [Safety Boundaries](docs/safety-boundaries.md), and [Known Limitations](docs/known-limitations.md). ## System requirements @@ -141,7 +173,7 @@ For users: - Windows 10 or Windows 11, x64. - Npcap for live capture or transmission. -- Administrator permission when required by the local Npcap/network configuration. +- Administrator permission only when required by local driver or adapter configuration. - An independent packet dissector or process-bus analyzer is recommended for verification. For developers: @@ -149,7 +181,7 @@ For developers: - .NET 8 SDK, feature band 8.0.4xx. - PowerShell 7+ recommended. - Visual Studio 2022, JetBrains Rider, or VS Code with C# tooling. -- Inno Setup 6.7.1 when reproducing the automated installer build locally. +- Inno Setup 6.7.1 when reproducing the automated installer build. ## Build from source @@ -159,83 +191,73 @@ cd arsvin .\build.ps1 ``` -NuGet versions are centrally managed and committed `packages.lock.json` files lock the resolved dependency graph. Validated CI and release paths restore with `--locked-mode`. +The resolved dependency graph is committed through `packages.lock.json`, and validated automation restores in locked mode. -Build all release artifacts except the installer: +Build release artifacts except the installer: ```powershell .\scripts\publish-release.ps1 -Version 0.4.0 ``` -Compatibility wrapper: - -```powershell -.\publish-win-x64.ps1 -Version 0.4.0 -``` - -Run tests with both repository coverage gates and retain TRX/Cobertura evidence: +Run tests with both coverage gates: ```powershell .\scripts\test-with-coverage.ps1 -MinimumWholeEngineLineCoverage 13 -MinimumLineCoverage 70 ``` -The current suite contains 74 deterministic tests. The complete shared `ARSVIN.Engine` baseline measures 13.35% line coverage across 16,312 instrumented production lines, with 2,178 covered lines. The protocol-core regression surface measures 70.47% across 2,120 lines, with 1,494 covered lines. CI enforces floors of 13% for the whole engine and 70% for protocol core. +The current baseline contains 74 deterministic tests. CI enforces the documented whole-engine and protocol-core coverage floors; current values are engineering regression evidence, not formal protocol conformance evidence. -Generate a CycloneDX SBOM after restoring the solution: - -```powershell -.\scripts\generate-sbom.ps1 -Version 0.4.0 -``` - -## Repository structure +## Repository architecture ```text -src/ARSVIN.Engine/ Shared production engine project and source ownership -src/ARSVIN.Engine/AR.Iec61850/ IEC 61850, SCL, SV, MMS, capture, diagnostics, and protocol code -src/ARSVIN.Engine/AR.Iec61850/SampledValues/Profiles/ Profile observation, detection, and comparison engine -src/ARSVIN.Engine/AR.Iec61850.Transports.Npcap/ Npcap transport implementation +src/ARSVIN.Engine/ Shared production engine +src/ARSVIN.Engine/AR.Iec61850/ IEC 61850, SCL, SV, MMS, capture, and diagnostics +src/ARSVIN.Engine/AR.Iec61850/SampledValues/Profiles/ + Profile observation and comparison infrastructure +src/ARSVIN.Engine/AR.Iec61850.Transports.Npcap/ + Npcap transport src/ARSVIN/ Publisher application -src/ARSVIN.Subscriber/ ArSubsv subscriber and visualization companion -tests/ARSVIN.Tests/ Deterministic engine and publisher regression tests -installer/ Inno Setup definition for the Windows suite -scripts/ Repeatable release packaging and validation scripts -docs/ Engineering, safety, and contributor documentation -samples/ SCL, COMTRADE, scenario, and evidence samples -site/ Static, SEO-ready GitHub Pages product site -.github/workflows/ CI, CodeQL, Pages, and release automation +src/ARSVIN.Subscriber/ ArSubsv Subscriber + tests/ARSVIN.Tests/ Deterministic regression tests +installer/ Windows installer definition +scripts/ Build, validation, packaging, and release automation +docs/ Engineering, safety, licensing, and provenance documentation +samples/ Synthetic and redistributable examples +site/ SEO-ready GitHub Pages product site ``` -The shared engine is compiled once as `ARSVIN.Engine`, and its source is physically owned by the same `src/ARSVIN.Engine` project used by Publisher, Subscriber, and Tests. - ## Documentation - [Documentation index](docs/index.md) - [Quick start](docs/quick-start.md) +- [Architecture](docs/architecture.md) - [SV standards and evidence research gate](docs/sv-research-gate.md) - [SV conformance and interoperability matrix](docs/sv-evidence-matrix.md) - [SV profile infrastructure](docs/sv-profile-infrastructure.md) -- [Profile detection output contract](docs/profile-detection-output.md) - [Subscriber verification app](docs/subscriber-verification-app.md) -- [ArSubsv SV scout companion](docs/arsubsv-sv-scout-companion.md) -- [SV profile support](docs/sv-profile-support.md) - [COMTRADE replay](docs/comtrade-replay.md) -- [Multi-stream publishing](docs/multi-stream.md) -- [Publisher evidence workflow](docs/p1-publisher-evidence-workflow.md) -- [Full publisher scenarios](docs/p2-full-publisher-scenarios.md) - [Safety boundaries](docs/safety-boundaries.md) -- [PTP and `smpSynch` compatibility](docs/ptp-and-smpsynch.md) - [Build and release](docs/build-and-release.md) +- [Licensing](docs/LICENSING.md) +- [External IP and provenance review](docs/EXTERNAL_IP_AND_PROVENANCE_REVIEW_2026-07-14.md) +- [Public wording and claim review](docs/WORDING_AND_CLAIM_REVIEW_2026-07-14.md) ## Security and responsible use -Do not attach confidential station SCL/SCD files, relay credentials, production packet captures, or internal network plans to public issues. Report vulnerabilities through GitHub Security Advisories as described in [SECURITY.md](SECURITY.md). +Do not attach confidential station SCL/SCD files, credentials, production captures, customer names, restricted network plans, or proprietary support material to public issues. Follow [SECURITY.md](SECURITY.md) and [SUPPORT.md](SUPPORT.md). ## Contributing -Focused engineering contributions are welcome. Read [CONTRIBUTING.md](CONTRIBUTING.md), keep changes reviewable, include test evidence where practical, and preserve explicit safety boundaries. +Contributions require the project [Contributor License Agreement](CONTRIBUTOR-LICENSE-AGREEMENT.md), a DCO sign-off on every commit, documented provenance, and any required employer authorization. Read [CONTRIBUTING.md](CONTRIBUTING.md). + +## Licensing + +The current `main` branch and current public release packages are licensed **only** under the GNU General Public License v3.0 or later (`GPL-3.0-or-later`). See [LICENSE](LICENSE). + +A separate negotiated commercial license is available for proprietary integration, OEM or white-label distribution, closed-source redistribution, private branches, support, training, and engineering services. [COMMERCIAL-LICENSE.md](COMMERCIAL-LICENSE.md) is an invitation to discuss terms, not an executed license. -## License +Revisions up to and including `9440f08b6909ef2dc93dd483cfdcb4e1e86077d0` were released under Apache-2.0 and remain available on `archive/apache-2.0-final`. Those historical grants apply only to those earlier revisions. See [docs/LICENSING.md](docs/LICENSING.md). -Copyright © 2026 Ari Sulistiono. +Third-party components retain their applicable licenses. See [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md). Names, logos, icons, and official-release branding are governed separately by [TRADEMARK.md](TRADEMARK.md). -Licensed under the [Apache License 2.0](LICENSE). Third-party dependency notices are documented in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md). +Copyright (C) 2026 Ari Sulistiono. \ No newline at end of file From 3db288cfb378d2d12c3bd2096e9d8557405a6ceb Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:04:16 +0700 Subject: [PATCH 13/69] Align contribution policy with GPL and commercial licensing --- CONTRIBUTING.md | 131 ++++++++++++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 55 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ac28852..0723d49 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,100 +1,121 @@ -# Contributing +# Contributing to ARSVIN Thank you for considering a contribution to ARSVIN. -ARSVIN is an engineering suite for IEC 61850 Sampled Values laboratory workflows. The project values clear code, cautious live-network behavior, reproducible test notes, and documentation that an engineer can use in the field. +ARSVIN is an IEC 61850 Sampled Values engineering suite for authorized laboratory, development, troubleshooting, commissioning-preparation, and education workflows. Contributions should improve observable engineering behavior without overstating safety, conformance, or interoperability. -## Project principles +## Licensing and acceptance + +The current community edition is `GPL-3.0-or-later` and the project maintains a separate commercial-licensing path. + +Before merge, contributors must: + +1. read and affirmatively accept [CONTRIBUTOR-LICENSE-AGREEMENT.md](CONTRIBUTOR-LICENSE-AGREEMENT.md); +2. add a Developer Certificate of Origin sign-off to every commit; +3. have the legal right and any required employer or organizational authorization to submit the contribution; and +4. identify any third-party material together with its provenance and license. + +Sign commits with: + +```text +Signed-off-by: Full Name +``` + +The CLA grants rights needed for GPL-compatible publication and a separate commercial path. It does not transfer ownership of the contributor’s work. + +## Engineering principles - Keep Publisher and Subscriber responsibilities explicit and independently testable. +- Keep protocol and transport behavior in the shared engine rather than duplicating it in application UI code. - Add analysis features only when they improve Sampled Values visibility, interoperability, troubleshooting, or evidence quality. -- Keep live packet capture and injection guarded, visible, and clearly labelled. -- Preserve Apache-2.0 compatibility. -- Prefer explicit engineering wording over marketing claims. -- Update documentation when behavior, UI, safety assumptions, or release packaging changes. -- Preserve committed NuGet lock files and immutable public releases. +- Keep live packet capture and transmission guarded, visible, and clearly labelled. +- Prefer scoped evidence language over universal marketing claims. +- Update documentation when behavior, UI, operational assumptions, licensing, or packaging changes. +- Preserve committed dependency lock files and immutable public releases. + +## Independent-development and provenance boundary + +External software may be used only as a lawfully licensed black-box interoperability endpoint within the applicable authorization and license boundary. + +Do not use external source, generated bindings, API composition, examples, tests, internal structures, documentation wording, screenshots, UI layouts, icons, reports, or extracted resources as implementation design material unless the project has documented rights to incorporate and relicense that material. + +Public fixtures should be synthetic or contributor-owned. Real SCL, COMTRADE, PCAP, screenshots, and diagnostics require documented sharing rights and sanitization. + +Do not submit: + +- confidential customer, employer, station, credential, or restricted network information; +- production captures or configuration files without explicit redistribution authority; +- proprietary manuals, screenshots, support responses, binaries, or copied UI assets; or +- unverified profile constants presented as normative requirements. ## Development setup Recommended environment: -- Windows 10/11 x64 -- .NET 8 SDK, feature band 8.0.4xx -- PowerShell 7+ -- Npcap for live packet capture/publishing tests -- Wireshark for packet inspection +- Windows 10 or Windows 11, x64; +- .NET 8 SDK, feature band 8.0.4xx; +- PowerShell 7+; +- Npcap for authorized live packet capture or publishing tests; and +- an independent packet dissector or process-bus analyzer for verification. -Build using the committed dependency graph: +Build with the committed dependency graph: ```powershell .\build.ps1 ``` -Run tests and produce coverage evidence: +Run tests and coverage gates: ```powershell -.\scripts\test-with-coverage.ps1 -MinimumLineCoverage 50 +.\scripts\test-with-coverage.ps1 -MinimumWholeEngineLineCoverage 13 -MinimumLineCoverage 70 ``` -Create portable release artifacts for the current source version: +Create portable release artifacts: ```powershell -.\scripts\publish-release.ps1 -Version 0.3.1 +.\scripts\publish-release.ps1 -Version 0.4.0 ``` ## Dependency updates NuGet versions are centrally managed in `Directory.Packages.props`, and each project commits `packages.lock.json`. -Normal builds and automation restore with locked mode. When deliberately changing a dependency: +When deliberately changing a dependency: -1. update the version in `Directory.Packages.props`, -2. regenerate lock files from the repository root, -3. review direct and transitive changes, -4. commit package-version and lock-file changes together. +1. update the central version; +2. regenerate lock files from the repository root; +3. review direct and transitive changes, license compatibility, and vulnerability output; and +4. commit the package version and lock-file changes together. ```powershell dotnet restore ARSVIN.sln --force-evaluate ``` -Do not hand-edit `packages.lock.json`. Unrelated lock-file churn should not be included in a pull request. +Do not hand-edit lock files or include unrelated lock-file churn. -## Pull request checklist +## Pull request expectations -Before opening a PR, please check: +A pull request should state: -- The change has a narrow engineering purpose. -- Both affected applications build in Release mode. -- Relevant unit tests were added or updated where practical. -- The protocol-core coverage floor still passes, and broader coverage changes are explained. -- Safety behavior is not weakened. -- Docs are updated for user-visible changes. -- Screenshots or Wireshark notes are included for UI / packet behavior changes. -- New dependencies are necessary, maintained, license-compatible, and represented in lock files. -- Release-workflow changes preserve tag-only publication and immutable existing releases. +- the engineering problem and application/engine boundary; +- the source of protocol requirements and test expectations; +- the evidence environment: automated test, simulator, loopback, isolated laboratory equipment, or approved commissioning environment; +- operational and data-handling impact; +- public wording or documentation changes; and +- any limitations not covered by the validation. -## Commit and branch style +Before opening a PR, verify: -Short, clear commit messages are preferred: - -```text -Fix VLAN TCI validation -Add COMTRADE replay guardrail -Document smpSynch compatibility mode -``` +- relevant Release builds and deterministic tests pass; +- whole-engine and protocol-core coverage gates remain satisfied; +- public-site, terminology, licensing, and provenance checks pass; +- active network behavior remains explicitly guarded; +- no claim implies formal conformance, deterministic timing, functional safety, cybersecurity approval, switching authority, or IED consumption proof; +- screenshots and captures are sanitized and legally shareable; and +- release changes preserve immutable existing releases and required legal notices. ## Reporting issues -Use GitHub Issues and include: - -- ARSVIN version or commit -- Application: Publisher or ArSubsv Subscriber -- Windows version -- Npcap version -- SCL/COMTRADE/PCAP sample if shareable -- Steps to reproduce -- Expected behavior -- Actual behavior -- Screenshots or Wireshark capture notes when relevant +Use the structured GitHub issue forms. Include the ARSVIN version, application, Windows and Npcap versions, reproduction steps, and the smallest sanitized evidence needed to explain the problem. -Do not upload confidential station SCL files, relay IP plans, credentials, or production network captures. +Never post confidential SCL, COMTRADE, PCAP, station addressing, credentials, customer identity, or proprietary third-party material in a public issue. \ No newline at end of file From 40efa692388a5ad59131cc7f9c84e28c1290781a Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:04:32 +0700 Subject: [PATCH 14/69] Update repository engineering guidance --- AGENTS.md | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 6074e8b..ae4c483 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,13 +1,32 @@ # Repository Guidance -ARSVIN is a focused IEC 61850 Sampled Values injector. +ARSVIN is an IEC 61850 Sampled Values engineering suite with a shared engine, ARSVIN Publisher, and ArSubsv Subscriber. -Priority order: +## Priority order -1. Correct SV injection behavior. -2. Clean public user workflow. -3. Multi-stream and COMTRADE reliability. -4. Release automation and documentation. -5. Avoid analyzer-style scope creep. +1. Observable and evidence-backed Sampled Values behavior. +2. Explicit operational guardrails for live capture and transmission. +3. Clear separation between Publisher, Subscriber, and shared engine responsibilities. +4. Repeatable SCL, COMTRADE, PCAP, scenario, test, and release workflows. +5. Accurate public documentation, licensing, provenance, and claim boundaries. +6. Performance and usability improvements that preserve engineering evidence. -Do not add broad station-analysis features unless they directly support SV injection. +## Architecture boundary + +Protocol parsing, stream generation, SCL semantics, profile observations, comparison logic, capture, and transport behavior belong in `ARSVIN.Engine`. WPF applications should consume typed engine contracts rather than reimplement protocol rules. + +## External-material boundary + +External software may be used only as a lawfully licensed black-box interoperability endpoint. Do not use unrelated source, API composition, examples, tests, internal structure, documentation wording, UI composition, screenshots, icons, reports, or extracted resources as implementation design material. + +Use synthetic or contributor-owned fixtures. Real SCL, COMTRADE, PCAP, screenshots, and diagnostics require documented authority to share and sanitization. + +## Public claim boundary + +Do not claim formal IEC 61850 conformance, universal interoperability, calibrated measurement, deterministic real-time execution, functional safety, cybersecurity certification, switching authority, or proof that another IED consumed a multicast stream. + +State the evidence source and use scoped terms such as implemented, tested, observed, provisional, unsupported, or not yet verified. + +## Licensing boundary + +Current community revisions are `GPL-3.0-or-later`. Historical Apache-2.0 revisions end at `9440f08b6909ef2dc93dd483cfdcb4e1e86077d0` and remain on `archive/apache-2.0-final`. Commercial rights require a separate negotiated agreement and can cover only rights controlled by the relevant copyright holder. \ No newline at end of file From 5fe20114041c47e88ef3e8ecabbc77d64417163e Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:04:54 +0700 Subject: [PATCH 15/69] Add licensing and provenance documentation index --- docs/index.md | 62 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/docs/index.md b/docs/index.md index f9cc9f2..485c54a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,32 +1,33 @@ # ARSVIN Documentation -ARSVIN is a focused IEC 61850 Sampled Values engineering suite for Windows. It includes ARSVIN Publisher for stream generation and ArSubsv Subscriber for live/PCAP reception, decoding, visualization, and receiver-side evidence. +ARSVIN is an IEC 61850 Sampled Values engineering suite for Windows. It includes ARSVIN Publisher for stream generation and ArSubsv Subscriber for live or PCAP reception, decoding, visualization, and receiver-side evidence. ## Start here -- [Quick Start](quick-start.md) — install the suite, choose Publisher or Subscriber, and begin with a safe workflow. -- [Safety Boundaries](safety-boundaries.md) — laboratory assumptions and responsible use. -- [Known Limitations](known-limitations.md) — current protocol and runtime boundaries. +- [Quick Start](quick-start.md) — install the suite, choose Publisher or Subscriber, and begin with a guarded offline or authorized test workflow. +- [Safety Boundaries](safety-boundaries.md) — laboratory assumptions, authorization, and responsible use. +- [Known Limitations](known-limitations.md) — current protocol, timing, evidence, and runtime boundaries. +- [Licensing](LICENSING.md) — current GPL community edition, historical Apache boundary, and commercial licensing path. ## Sampled Values standards and interoperability - [SV Standards and Evidence Research Gate](sv-research-gate.md) — authoritative source hierarchy, claim levels, evidence requirements, and research acceptance rules. -- [SV Conformance and Interoperability Matrix](sv-evidence-matrix.md) — verified, provisional, unknown, and out-of-scope requirements for 9-2LE-style, IEC 61869-9, and generic Layer-2 SV. +- [SV Conformance and Interoperability Matrix](sv-evidence-matrix.md) — implemented, provisional, unknown, and out-of-scope requirements for 9-2LE-style, IEC 61869-9, and generic Layer-2 SV. - [SV Profile Infrastructure](sv-profile-infrastructure.md) — transport-independent observed facts, evidence-aware definitions, confidence detection, and configuration-versus-wire comparison. -- [Profile Detection Output Contract](profile-detection-output.md) — compact confidence, evidence, and mismatch presentation rules. -- [Public Terminology Policy](public-terminology-policy.md) — neutral public wording and automated validation. -- `samples/sv-evidence` — safe evidence intake, anonymization rules, metadata, and minimum regression cases for real merging-unit captures. +- [Profile Detection Output Contract](profile-detection-output.md) — confidence, evidence, and mismatch presentation rules. +- [Public Terminology Policy](public-terminology-policy.md) — vendor-neutral public wording and automated validation. +- `samples/sv-evidence` — synthetic or authorized evidence intake, anonymization rules, metadata, and regression cases. ## Publisher workflows -- [SV Profile Support](sv-profile-support.md) — current IEC 61850 SV publishing support and limits. -- [Multi-Stream SV Publishing](multi-stream.md) — using multiple publisher slots. +- [SV Profile Support](sv-profile-support.md) — current publishing support and limits. +- [Multi-Stream SV Publishing](multi-stream.md) — multiple publisher slots. - [Publisher Session Engine](publisher-session-engine.md) — runtime session model. -- [Live Preflight Diagnostics](live-preflight-diagnostics.md) — preflight checks before live TX. -- [P0 Publisher Protocol Roadmap](p0-publisher-protocol-roadmap.md) — nofASDU, quality, timing, and PCAP foundation. -- [P1 Publisher Evidence Workflow](p1-publisher-evidence-workflow.md) — generated PCAP and Markdown evidence export. +- [Live Preflight Diagnostics](live-preflight-diagnostics.md) — checks before authorized live transmission. +- [P0 Publisher Protocol Roadmap](p0-publisher-protocol-roadmap.md) — `nofASDU`, quality, timing, and PCAP foundation. +- [P1 Publisher Evidence Workflow](p1-publisher-evidence-workflow.md) — generated PCAP and Markdown evidence. - [P2 Full Publisher Scenario Engine](p2-full-publisher-scenarios.md) — repeatable protection and process-bus scenarios. -- [Waveform Shape Panel](waveform-shape-panel.md) — per-phase and waveform-shaped publisher scenarios. +- [Waveform Shape Panel](waveform-shape-panel.md) — per-phase and waveform-shaped scenarios. ## Subscriber workflows @@ -39,7 +40,7 @@ ARSVIN is a focused IEC 61850 Sampled Values engineering suite for Windows. It i - [PTP and `smpSynch` Compatibility](ptp-and-smpsynch.md) — timing and synchronization boundaries. - [Sync Compatibility Mode](sync-compatibility-mode.md) — laboratory `smpSynch` behavior. -## Build, release, and public repository +## Build, release, and repository governance - [Architecture](architecture.md) - [Build and Release](build-and-release.md) @@ -47,11 +48,30 @@ ARSVIN is a focused IEC 61850 Sampled Values engineering suite for Windows. It i - [SEO and Public Launch Checklist](seo-public-launch-checklist.md) - [GitHub Repository Settings](github-repository-settings.md) - [Repository Audit](repository-audit.md) +- [External IP and Provenance Review — 2026-07-14](EXTERNAL_IP_AND_PROVENANCE_REVIEW_2026-07-14.md) +- [Public Wording and Claim Review — 2026-07-14](WORDING_AND_CLAIM_REVIEW_2026-07-14.md) -## Samples +## Project policies -- `samples/scl` — minimal and `nofASDU` sample SCL files. -- `samples/comtrade` — COMTRADE replay files. -- `samples/evidence` — sample Markdown evidence reports. -- `samples/scenarios` — publisher scenario notes and matrices. -- `samples/sv-evidence` — anonymized or synthetic profile-validation evidence packages. +- [Contributing](../CONTRIBUTING.md) +- [Contributor License Agreement](../CONTRIBUTOR-LICENSE-AGREEMENT.md) +- [Developer Certificate of Origin](../DCO.txt) +- [Security](../SECURITY.md) +- [Support](../SUPPORT.md) +- [Community conduct](../CODE_OF_CONDUCT.md) +- [GPL license](../LICENSE) +- [Commercial licensing](../COMMERCIAL-LICENSE.md) +- [Copyright](../COPYRIGHT.md) +- [Trademark and branding](../TRADEMARK.md) +- [Third-party notices](../THIRD_PARTY_NOTICES.md) + +## Documentation principles + +Public documentation should: + +- distinguish configured SCL expectations from observed wire traffic; +- distinguish transmitter evidence from receiver evidence and IED behavior; +- identify whether evidence comes from tests, loopback, laboratory equipment, or an approved commissioning environment; +- avoid universal interoperability, formal conformance, functional-safety, cybersecurity, and deterministic-timing claims; +- use synthetic or contributor-owned examples; and +- exclude confidential customer, employer, station, credential, and restricted network material. \ No newline at end of file From 80a1fa4d7597401a650c76e19a771463fd0267e0 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:05:10 +0700 Subject: [PATCH 16/69] Add licensing provenance and claim gates to PR template --- .github/pull_request_template.md | 51 ++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index b05ea9d..faccbcb 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,6 +1,10 @@ -## Summary +## Engineering problem -Describe the change, why it is needed, and the user or engineering impact. +Describe the change, why it is needed, and whether it belongs in the shared engine, Publisher, Subscriber, documentation, website, or release tooling. + +## Solution + +Summarize the implementation and any application/engine boundary changes. ## Type of change @@ -11,29 +15,46 @@ Describe the change, why it is needed, and the user or engineering impact. - [ ] Refactor - [ ] Build / CI - [ ] Release preparation -- [ ] Safety wording / guardrail +- [ ] Operational wording / guardrail +- [ ] Licensing / provenance -## Engineering notes +## Engineering and evidence notes -Explain any IEC 61850, Sampled Values, SCL/SCD, COMTRADE, PTP, timing, packet-layout, or UI behavior affected by this PR. Write **Not applicable** when the change is unrelated to runtime engineering behavior. +Explain any IEC 61850, Sampled Values, SCL/SCD, COMTRADE, timing, packet-layout, capture, or UI behavior. Identify the requirement source and evidence environment. Write **Not applicable** when unrelated to runtime behavior. -## Safety impact +## Operational impact - [ ] No runtime or live-network behavior changes -- [ ] Changes offline parsing, display, reporting, or PCAP behavior only -- [ ] Changes live capture behavior and was tested on an authorized isolated link -- [ ] Changes live packet publishing and was tested on an authorized isolated link -- [ ] Safety documentation or warnings were reviewed and updated where needed +- [ ] Offline parsing, display, reporting, or PCAP behavior only +- [ ] Live capture was tested only on an authorized isolated link +- [ ] Live transmission was tested only on an authorized isolated link +- [ ] Operational documentation and warnings were reviewed ## Validation +- [ ] Current-license, provenance, and public-wording checks passed - [ ] `dotnet build ARSVIN.sln -c Release` -- [ ] `dotnet test tests/ARSVIN.Tests/ARSVIN.Tests.csproj -c Release` -- [ ] Public-site validator passed, when applicable +- [ ] Relevant automated tests and coverage gates passed +- [ ] Public-site build and validator passed, when applicable - [ ] Release packaging and installer smoke test passed, when applicable -- [ ] Manual dry run tested, when applicable -- [ ] Live mode tested only on an isolated lab link, when applicable +- [ ] Simulator, loopback, or dry-run evidence recorded, when applicable +- [ ] Laboratory equipment evidence recorded, when applicable +- [ ] Public documentation updated for changed behavior or claims + +## Data and external-material boundary + +- [ ] No confidential customer, employer, station, credential, restricted network, or production data is included +- [ ] Any SCL, COMTRADE, PCAP, screenshot, or diagnostic sample is synthetic, contributor-owned, or documented as authorized and sanitized +- [ ] No external proprietary code, API composition, example, test, wording, screenshot, manual, report, asset, or UI design was copied or mechanically translated +- [ ] The change does not claim formal conformance, universal interoperability, calibrated measurement, deterministic timing, functional safety, cybersecurity approval, switching authority, or IED-consumption proof + +## Contribution licensing + +- [ ] I have read and affirmatively agree to `CONTRIBUTOR-LICENSE-AGREEMENT.md` +- [ ] I have the legal right and any required employer or organizational authorization to submit this contribution +- [ ] Every commit includes a DCO sign-off: `Signed-off-by: Name ` +- [ ] Any third-party material is identified with its license and provenance ## Evidence -Add relevant screenshots, sanitized Wireshark notes, test output, release artifact names, or a concise explanation when visual/packet evidence is not applicable. +Add the smallest relevant test output, screenshots, or sanitized protocol evidence. Explain what the evidence demonstrates and what it does not demonstrate. \ No newline at end of file From a4cc6ed5989a8446f28b4ca7e24748cec8542461 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:06:12 +0700 Subject: [PATCH 17/69] Update landing page for GPL and commercial licensing --- site/index.html | 208 +++++++++++++++++++++--------------------------- 1 file changed, 91 insertions(+), 117 deletions(-) diff --git a/site/index.html b/site/index.html index 6daf9b0..83cedbc 100644 --- a/site/index.html +++ b/site/index.html @@ -3,26 +3,26 @@ - ARSVIN — Open-Source IEC 61850 Sampled Values Publisher & Subscriber - + ARSVIN — IEC 61850 Sampled Values Publisher & Subscriber + - + - - + + - + - - + + @@ -39,7 +39,8 @@ "applicationCategory": "EngineeringApplication", "applicationSubCategory": "Substation automation and process bus engineering", "operatingSystem": "Windows 10, Windows 11", - "license": "https://www.apache.org/licenses/LICENSE-2.0", + "softwareVersion": "0.4.0", + "license": "https://spdx.org/licenses/GPL-3.0-or-later.html", "isAccessibleForFree": true, "codeRepository": "https://github.com/masarray/arsvin", "url": "https://masarray.github.io/arsvin/", @@ -55,7 +56,15 @@ "name": "Ari Sulistiono", "url": "https://github.com/masarray" }, - "description": "Apache-2.0 IEC 61850 Sampled Values Publisher and Subscriber suite for Windows with SCL-driven stream setup, COMTRADE replay, live and PCAP analysis, waveform, phasor, RMS, timing health, and evidence export." + "offers": [ + { + "@type": "Offer", + "price": "0", + "priceCurrency": "USD", + "category": "GPL community edition" + } + ], + "description": "Windows IEC 61850 Sampled Values Publisher and Subscriber suite for SCL-driven stream setup, COMTRADE replay, live and PCAP analysis, waveform, phasor, RMS, timing health, and engineering evidence." } @@ -69,7 +78,7 @@ "name": "What is ARSVIN?", "acceptedAnswer": { "@type": "Answer", - "text": "ARSVIN is an Apache-2.0 IEC 61850 Sampled Values engineering suite for Windows. It includes an SCL-driven Publisher and a live and PCAP Subscriber analysis companion." + "text": "ARSVIN is a GPL-3.0-or-later IEC 61850 Sampled Values engineering suite for Windows. It includes an SCL-driven Publisher and a live and PCAP Subscriber companion." } }, { @@ -77,7 +86,7 @@ "name": "Does ARSVIN require Npcap?", "acceptedAnswer": { "@type": "Answer", - "text": "Npcap is required for live raw Ethernet capture and transmission. Offline configuration, dry-run, and PCAP workflows can be used without live network access." + "text": "Npcap is required for live raw Ethernet capture and transmission. Offline configuration, dry-run, COMTRADE, and PCAP workflows can be used without live network access." } }, { @@ -85,15 +94,23 @@ "name": "Is ARSVIN a certified IEC 61850 test set?", "acceptedAnswer": { "@type": "Answer", - "text": "No. ARSVIN is laboratory-oriented engineering software. It is not calibrated, deterministic real-time equipment, a certified merging unit, or an IEC 61850 conformance test platform." + "text": "No. ARSVIN is engineering software for authorized laboratory and commissioning-support workflows. It is not calibrated deterministic real-time equipment, a certified merging unit, or a formal conformance platform." } }, { "@type": "Question", - "name": "Can ARSVIN prove that a protection IED subscribed to an SV stream?", + "name": "Can ARSVIN prove that an IED consumed an SV stream?", "acceptedAnswer": { "@type": "Answer", - "text": "No. IEC 61850 Sampled Values is multicast and has no application-layer acknowledgement. ARSVIN can show what the Publisher generated and what the selected PC or NIC received, but not prove IED consumption." + "text": "No. Sampled Values multicast has no application-layer acknowledgement. ARSVIN records what the Publisher generated and what the selected computer or adapter received, but it does not prove IED consumption or process action." + } + }, + { + "@type": "Question", + "name": "Is commercial licensing available?", + "acceptedAnswer": { + "@type": "Answer", + "text": "A separate negotiated commercial path is available for proprietary integration, OEM or white-label distribution, closed-source redistribution, private branches, and contractual support. The repository notice is an invitation to discuss terms, not an executed commercial license." } } ] @@ -112,7 +129,7 @@ Capabilities Docs Downloads - Safety + Licensing GitHub @@ -120,43 +137,43 @@
-

Apache-2.0 · Windows x64 · IEC 61850 laboratory engineering

-

Sampled Values publishing and analysis, without a black box.

-

ARSVIN combines an SCL-driven SV Publisher with a focused Subscriber companion for live capture, PCAP replay, decoded values, waveform, phasor, RMS, stream health, profile evidence, and engineering reports.

+

GPL-3.0-or-later · Windows x64 · Authorized engineering workflows

+

Generate Sampled Values. Inspect what arrives. Preserve the evidence.

+

ARSVIN combines an SCL-driven SV Publisher with ArSubsv Subscriber for COMTRADE replay, live and PCAP capture, decoded values, waveform, phasor, RMS, continuity diagnostics, profile evidence, and engineering reports.

- Open source - Portable EXEs - Installer + GPL community edition + Commercial path SBOM + SHA-256 + Artifact attestations
ArSubsv live analysis interface showing channel values, phasor, voltage waveform, and current waveform -
Real Subscriber workspace — channel data, phasor, voltage, and current analysis.
+
Actual Subscriber workspace — channels, phasor, voltage, and current analysis.
-

One repository, two focused tools

-

Generate the stream. Inspect what arrives.

-

Publisher and Subscriber remain separate applications so each workflow stays understandable, testable, and honest about what it proves.

+

One repository, two focused applications

+

Transmitter evidence and receiver evidence stay separate.

+

Publisher and Subscriber have distinct responsibilities so each workflow remains understandable, testable, and explicit about what it proves.

TX

ARSVIN Publisher

-

Build repeatable SV streams from SCL, manual values, per-phase scenarios, waveform shaping, or COMTRADE records.

+

Build repeatable streams from SCL, manual values, scenarios, waveform shaping, or COMTRADE records.

    -
  • SCL/SCD stream setup
  • +
  • SCL and SCD stream setup
  • Dataset-aware payload generation
  • -
  • Multi-ASDU frame packing
  • +
  • Multi-ASDU packing and timing health
  • Generated PCAP and evidence report
@@ -165,7 +182,7 @@

ARSVIN Publisher

RX

ArSubsv Subscriber

-

Discover and decode live or recorded SV traffic, bind streams to SCL, and inspect receiver-side behavior.

+

Discover and decode live or recorded traffic, bind streams to SCL, and inspect receiver-side behavior.

  • Live Npcap capture and PCAP import
  • Stream and smpCnt health
  • @@ -181,22 +198,22 @@

    ArSubsv Subscriber

    Actual Windows interfaces

    -

    See the engineering workflow before downloading.

    -

    These are captures from the Publisher and Subscriber applications, not generic product mockups.

    +

    Review the workflow before sending a frame.

    +

    These images are captures from the project applications, not generic product mockups or external-product references.

    - ARSVIN Publisher SV Setup with SCL stream selection, source modes, network fields, and manual output controls -
    Publisher SV Setup — stream, adapter, network, mode, and output configuration.
    + ARSVIN Publisher SV setup with SCL stream selection, source modes, network fields, and manual output controls +
    Publisher setup — stream, adapter, network, source, and output configuration.
    ArSubsv live analysis with channel table, phasor plot, voltage waveform, and current waveform -
    Subscriber analysis — decoded channels, phasor, voltage, and current views.
    +
    Subscriber analysis — decoded channels, phasor, voltage, and current.
    - ArSubsv stream monitor with discovered SV streams, voltage and current waveforms, phasor view, and RMS values -
    Stream monitor — discovered Sampled Values streams, waveform, phasor, and RMS inspection.
    + ArSubsv stream monitor with discovered Sampled Values streams, voltage and current waveforms, phasor view, and RMS values +
    Stream monitor — discovered traffic, waveform, phasor, RMS, and continuity inspection.
@@ -204,13 +221,13 @@

See the engineering workflow before downloading.

Engineering workflow

-

Useful visibility from configuration to evidence.

+

Trace configuration, observed traffic, and evidence without overclaiming.

01

Configure from SCL

Reuse APPID, destination MAC, VLAN, svID, dataset, confRev, sample rate, and packing.

02

Generate scenarios

Use manual values, ramps, faults, waveform shaping, sequence components, or COMTRADE replay.

03

Inspect stream health

Expose timing, continuity, counters, payload layout, decoded values, and configuration differences.

-
04

Preserve evidence

Export PCAP and Markdown reports for independent review, troubleshooting, and repeatable laboratory records.

+
04

Preserve evidence

Export PCAP and Markdown reports for independent review and repeatable laboratory records.

@@ -218,113 +235,70 @@

Useful visibility from configuration to evidence.

Search-indexable engineering documentation

-

Understand the workflow before sending a frame.

-

Repository guides are published as dedicated HTML pages with canonical metadata, structured data, navigation, and sitemap discovery.

+

Understand the boundary before enabling live Ethernet.

+

Documentation is published as dedicated HTML pages with canonical metadata, structured data, navigation, and sitemap discovery.

-
01

Quick Start

Install the suite and begin with an authorized dry run, PCAP, or isolated link.

-
02

SV Profile Support

Review current profile support, generic payload behavior, and explicit technical boundaries.

-
03

Subscriber Verification

Inspect live or recorded streams, continuity, decoded values, waveform, phasor, RMS, and evidence.

-
04

Safety Boundaries

Understand laboratory assumptions, evidence limits, and responsible live-network use.

+
01

Quick Start

Begin with a dry run, synthetic sample, PCAP file, or authorized isolated link.

+
02

SV Profile Support

Review implemented behavior, generic payload support, and explicit limitations.

+ +
04

Licensing

Understand GPL community rights, historical revisions, and the separate commercial path.

-

Windows release options

-

Installer or direct portable applications.

-

Public release files use stable names so the latest download links remain predictable.

+

Reproducible Windows releases

+

Choose the suite, one portable application, or verification files.

-
- - EXE - ARSVIN Suite InstallerPublisher, Subscriber, shortcuts, documentation, and uninstaller - Download - - - EXE - Publisher PortableSelf-contained single-file application - Download - - - EXE - Subscriber PortableSelf-contained single-file application - Download - - - ZIP - Portable SuiteBoth applications, documentation, notices, and samples - Download - +
+
SETUP

ARSVIN-Suite-Setup-win-x64.exe

Publisher, Subscriber, documentation, legal notices, shortcuts, and uninstaller.

+
ZIP

ARSVIN-win-x64-portable.zip

Portable suite folder with both applications and required notices.

+
TX

ARSVIN-Publisher-win-x64.exe

Self-contained single-file Publisher.

+
RX

ArSubsv-Subscriber-win-x64.exe

Self-contained single-file Subscriber.

-

Current binaries are unsigned and may trigger a Windows SmartScreen warning. Npcap is not bundled. Verify downloads with SHA256SUMS.txt and review the release SBOM.

+

Releases also provide ARSVIN-SBOM.cdx.json and SHA256SUMS.txt. Npcap is installed separately and is not silently bundled.

-
-
-
-

Explicit boundaries

-

Designed for controlled laboratory use.

-
-
-

ARSVIN can transmit and capture raw Ethernet frames. Use isolated networks, point-to-point links, or networks where you have explicit authorization.

-

It is not a certified protection test set, calibrated merging unit, deterministic real-time platform, production process-bus monitor, or IEC 61850 conformance tool.

- Read safety boundaries → +
+
+
+

Operational boundary

+

Software checks do not establish site authorization or process safety.

+

Use live capture and transmission only under an approved test plan and network boundary. ARSVIN does not establish isolation, switching authority, functional safety, cybersecurity approval, calibrated measurement, deterministic timing, or IED consumption.

-
-
-

FAQ

-

Clear answers before live traffic.

+
+
+

Clear licensing model

+

GPL community edition with a separate negotiated commercial path.

+

Current public source and releases are licensed only under GPL-3.0-or-later. Commercial terms are available for proprietary integration, OEM or white-label distribution, closed-source redistribution, private branches, and contractual support.

-
- What does the Subscriber prove? -

It proves that the selected PC or NIC received and decoded the stream. It does not prove that a relay or other IED consumed the multicast traffic.

-
-
- Does ARSVIN require Npcap? -

Npcap is required for live raw Ethernet capture and transmission. PCAP import, documentation, configuration, and dry-run workflows do not require live network access.

-
-
- Is the installer code-signed? -

Not currently. Release assets include SHA-256 checksums, an SBOM, and repository workflow provenance, but Windows may still show an unknown-publisher warning.

-
-
- Can ARSVIN replace a calibrated test set or certified analyzer? -

No. ARSVIN is transparent engineering software for controlled laboratory workflows, education, development, and troubleshooting support.

-
-
- -
-
-
-

Build, inspect, improve

-

Open engineering for IEC 61850 Sampled Values.

-
- +
+
GPL

Community edition

Use, study, modify, and redistribute under GPL-3.0-or-later and its source-distribution obligations.

Read the license

+
OEM

Commercial discussion

The repository notice invites negotiation but grants no additional rights by itself. Commercial rights cover only material controlled by the relevant copyright holder.

Commercial licensing notice

+

Earlier revisions through commit 9440f08b6909ef2dc93dd483cfdcb4e1e86077d0 remain available under their historical Apache-2.0 grant on archive/apache-2.0-final. That historical grant is not a current Apache-or-GPL choice for later releases.

- + \ No newline at end of file From c2a43f75653bbeca7e6f1427c31c0f4e6b78dc16 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:07:25 +0700 Subject: [PATCH 18/69] Add GPL-aware static documentation site builder --- scripts/public_site_builder.py | 354 +++++++++++++++++++++++++++++++++ 1 file changed, 354 insertions(+) create mode 100644 scripts/public_site_builder.py diff --git a/scripts/public_site_builder.py b/scripts/public_site_builder.py new file mode 100644 index 0000000..9c4d238 --- /dev/null +++ b/scripts/public_site_builder.py @@ -0,0 +1,354 @@ +#!/usr/bin/env python3 +"""Build the ARSVIN product site and searchable HTML documentation.""" + +from __future__ import annotations + +import html +import json +import re +import shutil +from dataclasses import dataclass +from pathlib import Path +from urllib.parse import urlsplit + +BASE_URL = "https://masarray.github.io/arsvin/" +REPO_URL = "https://github.com/masarray/arsvin" + + +@dataclass(frozen=True) +class DocPage: + source: Path + slug: str + title: str + description: str + + +def plain(text: str) -> str: + text = re.sub(r"`([^`]+)`", r"\1", text) + text = re.sub(r"!\[([^\]]*)\]\([^)]*\)", r"\1", text) + text = re.sub(r"\[([^\]]+)\]\([^)]*\)", r"\1", text) + text = re.sub(r"[*_~>#]", "", text) + return re.sub(r"\s+", " ", text).strip() + + +def slugify(text: str) -> str: + value = re.sub(r"[^a-z0-9]+", "-", plain(text).lower()).strip("-") + return value or "section" + + +def metadata(path: Path) -> tuple[str, str]: + lines = path.read_text(encoding="utf-8").splitlines() + title = path.stem.replace("-", " ").title() + start = 0 + for index, line in enumerate(lines): + match = re.match(r"^#\s+(.+?)\s*$", line) + if match: + title = plain(match.group(1)) + start = index + 1 + break + + paragraph: list[str] = [] + for line in lines[start:]: + value = line.strip() + if not value: + if paragraph: + break + continue + if value.startswith(("#", "- ", "* ", ">", "```", "|")): + if paragraph: + break + continue + paragraph.append(value) + + description = plain(" ".join(paragraph)) or f"ARSVIN engineering documentation for {title}." + if len(description) > 158: + description = description[:155].rsplit(" ", 1)[0] + "..." + return title, description + + +def rewrite_link(target: str, current_slug: str, docs: dict[str, DocPage]) -> str: + target = html.unescape(target.strip()) + if not target or target.startswith("#"): + return target + if re.match(r"^(?:https?:|mailto:|tel:|data:)", target, re.IGNORECASE): + return target + + parsed = urlsplit(target) + path = parsed.path.replace("\\", "/") + fragment = f"#{parsed.fragment}" if parsed.fragment else "" + + if path.endswith(".md"): + normalized = path + while normalized.startswith("./"): + normalized = normalized[2:] + if normalized.startswith("../"): + return f"{REPO_URL}/blob/main/{normalized[3:]}{fragment}" + name = Path(normalized).name + page = docs.get(name) + if page: + if current_slug == "index": + base = "./" if page.slug == "index" else f"{page.slug}/" + else: + base = "../" if page.slug == "index" else f"../{page.slug}/" + return base + fragment + return f"{REPO_URL}/blob/main/docs/{normalized}{fragment}" + + if path.startswith("samples/") or path.startswith("src/"): + return f"{REPO_URL}/tree/main/{path}{fragment}" + return target + + +def inline(text: str, current_slug: str, docs: dict[str, DocPage]) -> str: + code: list[str] = [] + + def protect(match: re.Match[str]) -> str: + token = f"@@CODE{len(code)}@@" + code.append(f"{html.escape(match.group(1), quote=False)}") + return token + + text = re.sub(r"`([^`]+)`", protect, text) + text = html.escape(text, quote=False) + + def image(match: re.Match[str]) -> str: + alt = html.escape(match.group(1), quote=True) + src = html.escape(rewrite_link(html.unescape(match.group(2)), current_slug, docs), quote=True) + return f'{alt}' + + def link(match: re.Match[str]) -> str: + label = match.group(1) + href = rewrite_link(html.unescape(match.group(2)), current_slug, docs) + escaped = html.escape(href, quote=True) + external = bool(re.match(r"^https?://", href, re.IGNORECASE)) + attrs = ' target="_blank" rel="noopener noreferrer"' if external else "" + return f'{label}' + + text = re.sub(r"!\[([^\]]*)\]\(([^)]+)\)", image, text) + text = re.sub(r"\[([^\]]+)\]\(([^)]+)\)", link, text) + text = re.sub(r"\*\*([^*]+)\*\*", r"\1", text) + text = re.sub(r"__([^_]+)__", r"\1", text) + text = re.sub(r"(?\1", text) + + for index, value in enumerate(code): + text = text.replace(f"@@CODE{index}@@", value) + return text + + +def table_separator(line: str) -> bool: + cells = [cell.strip() for cell in line.strip().strip("|").split("|")] + return bool(cells) and all(re.fullmatch(r":?-{3,}:?", cell or "") for cell in cells) + + +def markdown_to_html(markdown: str, current_slug: str, docs: dict[str, DocPage]) -> str: + lines = markdown.splitlines() + output: list[str] = [] + used_ids: dict[str, int] = {} + first_h1 = False + index = 0 + + def anchor(text: str) -> str: + base = slugify(text) + count = used_ids.get(base, 0) + used_ids[base] = count + 1 + return base if count == 0 else f"{base}-{count + 1}" + + while index < len(lines): + value = lines[index].strip() + if not value: + index += 1 + continue + + fence = re.match(r"^```\s*([A-Za-z0-9_+.-]*)\s*$", value) + if fence: + language = fence.group(1) + block: list[str] = [] + index += 1 + while index < len(lines) and not re.match(r"^```\s*$", lines[index].strip()): + block.append(lines[index]) + index += 1 + index += 1 if index < len(lines) else 0 + attr = f' class="language-{html.escape(language, quote=True)}"' if language else "" + output.append(f"
{html.escape(chr(10).join(block), quote=False)}
") + continue + + heading = re.match(r"^(#{1,6})\s+(.+?)\s*#*\s*$", value) + if heading: + level = len(heading.group(1)) + text = heading.group(2) + if level == 1: + if first_h1: + level = 2 + else: + first_h1 = True + output.append(f'{inline(text, current_slug, docs)}') + index += 1 + continue + + if index + 1 < len(lines) and "|" in value and table_separator(lines[index + 1]): + headers = [cell.strip() for cell in value.strip("|").split("|")] + index += 2 + rows: list[list[str]] = [] + while index < len(lines): + candidate = lines[index].strip() + if not candidate or "|" not in candidate: + break + rows.append([cell.strip() for cell in candidate.strip("|").split("|")]) + index += 1 + output.append('
') + output.extend(f"" for cell in headers) + output.append("") + for row in rows: + padded = row + [""] * max(0, len(headers) - len(row)) + output.append("" + "".join(f"" for cell in padded[: len(headers)]) + "") + output.append("
{inline(cell, current_slug, docs)}
{inline(cell, current_slug, docs)}
") + continue + + unordered = re.match(r"^[-*+]\s+(.+)$", value) + ordered = re.match(r"^\d+[.)]\s+(.+)$", value) + if unordered or ordered: + tag = "ul" if unordered else "ol" + output.append(f"<{tag}>") + while index < len(lines): + candidate = lines[index].strip() + match = re.match(r"^[-*+]\s+(.+)$", candidate) if tag == "ul" else re.match(r"^\d+[.)]\s+(.+)$", candidate) + if not match: + break + output.append(f"
  • {inline(match.group(1), current_slug, docs)}
  • ") + index += 1 + output.append(f"") + continue + + if value.startswith(">"): + quoted: list[str] = [] + while index < len(lines) and lines[index].strip().startswith(">"): + quoted.append(lines[index].strip()[1:].lstrip()) + index += 1 + output.append(f"

    {inline(' '.join(quoted), current_slug, docs)}

    ") + continue + + paragraph: list[str] = [] + while index < len(lines): + candidate = lines[index].strip() + if not candidate: + break + if re.match(r"^(?:#{1,6}\s|```|[-*+]\s+|\d+[.)]\s+|>)", candidate): + break + if index + 1 < len(lines) and "|" in candidate and table_separator(lines[index + 1]): + break + paragraph.append(candidate) + index += 1 + if paragraph: + output.append(f"

    {inline(' '.join(paragraph), current_slug, docs)}

    ") + else: + index += 1 + + if not first_h1: + output.insert(0, '

    Documentation

    ') + return "\n".join(output) + + +def render(page: DocPage, pages: list[DocPage], docs: dict[str, DocPage]) -> str: + is_index = page.slug == "index" + prefix = "../" if is_index else "../../" + canonical = f"{BASE_URL}docs/" if is_index else f"{BASE_URL}docs/{page.slug}/" + source_url = f"{REPO_URL}/blob/main/docs/{page.source.name}" + body = markdown_to_html(page.source.read_text(encoding="utf-8"), page.slug, docs) + nav_items = [] + for item in pages: + href = ("./" if item.slug == "index" else f"{item.slug}/") if is_index else ("../" if item.slug == "index" else f"../{item.slug}/") + active = ' class="active" aria-current="page"' if item.slug == page.slug else "" + nav_items.append(f'
  • {html.escape(item.title)}
  • ') + structured = json.dumps({ + "@context": "https://schema.org", + "@type": "TechArticle", + "headline": page.title, + "description": page.description, + "url": canonical, + "license": "https://spdx.org/licenses/GPL-3.0-or-later.html", + "isPartOf": {"@type": "WebSite", "name": "ARSVIN", "url": BASE_URL}, + "author": {"@type": "Person", "name": "Ari Sulistiono", "url": "https://github.com/masarray"}, + }, ensure_ascii=False, separators=(",", ":")) + + return f''' + + + + + {html.escape(page.title)} | ARSVIN Documentation + + + + + + + + + + + + + + + + + +
    + ARSVIN + + GitHub +
    +
    + + +
    + + + + +''' + + +def build(repo_root: Path, output: Path) -> None: + site = repo_root / "site" + docs_dir = repo_root / "docs" + if not site.is_dir() or not docs_dir.is_dir(): + raise SystemExit("Expected site/ and docs/ directories under the repository root.") + if output.exists(): + shutil.rmtree(output) + shutil.copytree(site, output, ignore=shutil.ignore_patterns("docs")) + + pages_by_name: dict[str, DocPage] = {} + for source in sorted(docs_dir.glob("*.md")): + title, description = metadata(source) + slug = "index" if source.name == "index.md" else source.stem + pages_by_name[source.name] = DocPage(source, slug, title, description) + if "index.md" not in pages_by_name: + raise SystemExit("docs/index.md is required.") + + pages: list[DocPage] = [pages_by_name["index.md"]] + pages.extend(page for name, page in sorted(pages_by_name.items()) if name != "index.md") + docs_output = output / "docs" + docs_output.mkdir(parents=True, exist_ok=True) + for page in pages: + target = docs_output / "index.html" if page.slug == "index" else docs_output / page.slug / "index.html" + target.parent.mkdir(parents=True, exist_ok=True) + target.write_text(render(page, pages, pages_by_name), encoding="utf-8", newline="\n") + + index = [{"title": page.title, "description": page.description, "url": "./" if page.slug == "index" else f"{page.slug}/", "source": page.source.name} for page in pages] + (docs_output / "search-index.json").write_text(json.dumps(index, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") + + urls = [BASE_URL] + [BASE_URL + "docs/" if page.slug == "index" else BASE_URL + f"docs/{page.slug}/" for page in pages] + sitemap = ['', ''] + for url in urls: + sitemap.extend([" ", f" {html.escape(url)}", " "]) + sitemap.append("") + (output / "sitemap.xml").write_text("\n".join(sitemap) + "\n", encoding="utf-8") + (output / ".nojekyll").write_text("", encoding="utf-8") + print(f"Built public site: {output}") + print(f"Generated documentation pages: {len(pages)}") \ No newline at end of file From a8862b1e8e6b6e660dc20f6bbd8d584bedb1f0d4 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:07:40 +0700 Subject: [PATCH 19/69] Route public site generation through GPL-aware builder --- scripts/build-public-site.py | 454 +---------------------------------- 1 file changed, 4 insertions(+), 450 deletions(-) diff --git a/scripts/build-public-site.py b/scripts/build-public-site.py index afeef8d..01c707d 100644 --- a/scripts/build-public-site.py +++ b/scripts/build-public-site.py @@ -1,458 +1,12 @@ #!/usr/bin/env python3 +"""CLI wrapper for the ARSVIN public-site builder.""" + from __future__ import annotations import argparse -import html -import json -import re -import shutil -from dataclasses import dataclass from pathlib import Path -from urllib.parse import urlsplit, urlunsplit - -BASE_URL = "https://masarray.github.io/arsvin/" -REPO_URL = "https://github.com/masarray/arsvin" - - -@dataclass(frozen=True) -class DocPage: - source: Path - slug: str - title: str - description: str - - -def slugify(value: str) -> str: - value = re.sub(r"<[^>]+>", "", value) - value = re.sub(r"[`*_~]", "", value) - value = value.lower().strip() - value = re.sub(r"[^a-z0-9]+", "-", value) - return value.strip("-") or "section" - - -def strip_markdown(value: str) -> str: - value = re.sub(r"`([^`]+)`", r"\1", value) - value = re.sub(r"!\[([^\]]*)\]\([^)]*\)", r"\1", value) - value = re.sub(r"\[([^\]]+)\]\([^)]*\)", r"\1", value) - value = re.sub(r"[*_~>#]", "", value) - return re.sub(r"\s+", " ", value).strip() - - -def page_metadata(path: Path) -> tuple[str, str]: - lines = path.read_text(encoding="utf-8").splitlines() - title = path.stem.replace("-", " ").title() - title_index = -1 - for index, line in enumerate(lines): - match = re.match(r"^#\s+(.+?)\s*$", line) - if match: - title = strip_markdown(match.group(1)) - title_index = index - break - - paragraph: list[str] = [] - for line in lines[title_index + 1 :]: - stripped = line.strip() - if not stripped: - if paragraph: - break - continue - if stripped.startswith(("#", "- ", "* ", ">", "```", "|")): - if paragraph: - break - continue - paragraph.append(stripped) - - description = strip_markdown(" ".join(paragraph)) - if not description: - description = f"ARSVIN engineering documentation for {title}." - if len(description) > 158: - description = description[:155].rsplit(" ", 1)[0] + "..." - return title, description - - -def rewrite_link(target: str, current_slug: str) -> str: - target = html.unescape(target.strip()) - if not target or target.startswith("#"): - return target - if re.match(r"^(?:https?:|mailto:|tel:|data:)", target, re.IGNORECASE): - return target - - parts = urlsplit(target) - path = parts.path.replace("\\", "/") - fragment = parts.fragment - query = parts.query - - if path.endswith(".md"): - normalized = path - while normalized.startswith("./"): - normalized = normalized[2:] - if normalized.startswith("../"): - github_target = f"{REPO_URL}/blob/main/{normalized[3:]}" - return urlunsplit(("https", "github.com", github_target.split("github.com/", 1)[1], query, fragment)) - - stem = Path(normalized).stem - parent = Path(normalized).parent.as_posix() - if parent not in (".", ""): - github_target = f"{REPO_URL}/blob/main/docs/{normalized}" - return urlunsplit(("https", "github.com", github_target.split("github.com/", 1)[1], query, fragment)) - - if current_slug == "index": - href = "./" if stem == "index" else f"{stem}/" - else: - href = "../" if stem == "index" else f"../{stem}/" - if query: - href += f"?{query}" - if fragment: - href += f"#{fragment}" - return href - - return target - - -def inline_markdown(text: str, current_slug: str) -> str: - code_values: list[str] = [] - - def code_repl(match: re.Match[str]) -> str: - token = f"@@ARSVINCODE{len(code_values)}@@" - code_values.append(f"{html.escape(match.group(1), quote=False)}") - return token - - text = re.sub(r"`([^`]+)`", code_repl, text) - text = html.escape(text, quote=False) - - def image_repl(match: re.Match[str]) -> str: - alt = match.group(1) - src = rewrite_link(html.unescape(match.group(2)), current_slug) - return f'{alt}' - - def link_repl(match: re.Match[str]) -> str: - label = match.group(1) - target = rewrite_link(html.unescape(match.group(2)), current_slug) - external = bool(re.match(r"^https?://", target, re.IGNORECASE)) - attrs = ' target="_blank" rel="noopener noreferrer"' if external else "" - return f'{label}' - - text = re.sub(r"!\[([^\]]*)\]\(([^)]+)\)", image_repl, text) - text = re.sub(r"\[([^\]]+)\]\(([^)]+)\)", link_repl, text) - text = re.sub(r"\*\*([^*]+)\*\*", r"\1", text) - text = re.sub(r"__([^_]+)__", r"\1", text) - text = re.sub(r"(?\1", text) - - for index, value in enumerate(code_values): - text = text.replace(f"@@ARSVINCODE{index}@@", value) - return text - - -def is_table_separator(line: str) -> bool: - cells = [cell.strip() for cell in line.strip().strip("|").split("|")] - return bool(cells) and all(re.fullmatch(r":?-{3,}:?", cell or "") for cell in cells) - - -def markdown_to_html(markdown: str, current_slug: str) -> str: - lines = markdown.splitlines() - output: list[str] = [] - used_ids: dict[str, int] = {} - first_h1_seen = False - index = 0 - - def unique_id(text: str) -> str: - base = slugify(strip_markdown(text)) - count = used_ids.get(base, 0) - used_ids[base] = count + 1 - return base if count == 0 else f"{base}-{count + 1}" - - while index < len(lines): - line = lines[index] - stripped = line.strip() - - if not stripped: - index += 1 - continue - - fence = re.match(r"^```\s*([A-Za-z0-9_+.-]*)\s*$", stripped) - if fence: - language = fence.group(1) - code_lines: list[str] = [] - index += 1 - while index < len(lines) and not re.match(r"^```\s*$", lines[index].strip()): - code_lines.append(lines[index]) - index += 1 - if index < len(lines): - index += 1 - class_attr = f' class="language-{html.escape(language, quote=True)}"' if language else "" - output.append(f"
    {html.escape(chr(10).join(code_lines), quote=False)}
    ") - continue - - heading = re.match(r"^(#{1,6})\s+(.+?)\s*#*\s*$", stripped) - if heading: - level = len(heading.group(1)) - text = heading.group(2) - if level == 1: - if first_h1_seen: - level = 2 - else: - first_h1_seen = True - anchor = unique_id(text) - output.append(f'{inline_markdown(text, current_slug)}') - index += 1 - continue - - if index + 1 < len(lines) and "|" in stripped and is_table_separator(lines[index + 1]): - headers = [cell.strip() for cell in stripped.strip("|").split("|")] - index += 2 - rows: list[list[str]] = [] - while index < len(lines): - candidate = lines[index].strip() - if not candidate or "|" not in candidate: - break - rows.append([cell.strip() for cell in candidate.strip("|").split("|")]) - index += 1 - output.append('
    ') - output.extend(f"" for cell in headers) - output.append("") - for row in rows: - padded = row + [""] * max(0, len(headers) - len(row)) - output.append("") - output.extend(f"" for cell in padded[: len(headers)]) - output.append("") - output.append("
    {inline_markdown(cell, current_slug)}
    {inline_markdown(cell, current_slug)}
    ") - continue - - unordered = re.match(r"^[-*+]\s+(.+)$", stripped) - ordered = re.match(r"^\d+[.)]\s+(.+)$", stripped) - if unordered or ordered: - tag = "ul" if unordered else "ol" - output.append(f"<{tag}>") - while index < len(lines): - candidate = lines[index].strip() - match = re.match(r"^[-*+]\s+(.+)$", candidate) if tag == "ul" else re.match(r"^\d+[.)]\s+(.+)$", candidate) - if not match: - break - output.append(f"
  • {inline_markdown(match.group(1), current_slug)}
  • ") - index += 1 - output.append(f"") - continue - - if stripped.startswith(">"): - quoted: list[str] = [] - while index < len(lines) and lines[index].strip().startswith(">"): - quoted.append(lines[index].strip()[1:].lstrip()) - index += 1 - output.append(f"

    {inline_markdown(' '.join(quoted), current_slug)}

    ") - continue - - if re.fullmatch(r"(?:-{3,}|\*{3,}|_{3,})", stripped): - output.append("
    ") - index += 1 - continue - - paragraph: list[str] = [] - while index < len(lines): - candidate = lines[index].strip() - if not candidate: - break - if re.match(r"^(?:#{1,6}\s|```|[-*+]\s+|\d+[.)]\s+|>|(?:-{3,}|\*{3,}|_{3,})$)", candidate): - break - if index + 1 < len(lines) and "|" in candidate and is_table_separator(lines[index + 1]): - break - paragraph.append(candidate) - index += 1 - if paragraph: - output.append(f"

    {inline_markdown(' '.join(paragraph), current_slug)}

    ") - else: - output.append(f"

    {inline_markdown(stripped, current_slug)}

    ") - index += 1 - - if not first_h1_seen: - output.insert(0, '

    Documentation

    ') - return "\n".join(output) - - -def docs_order(docs_dir: Path, pages_by_name: dict[str, DocPage]) -> list[DocPage]: - ordered: list[DocPage] = [] - seen: set[str] = set() - index_path = docs_dir / "index.md" - if index_path.exists(): - for match in re.finditer(r"\[[^\]]+\]\(([^)#?]+\.md)(?:#[^)]+)?\)", index_path.read_text(encoding="utf-8")): - name = Path(match.group(1)).name - page = pages_by_name.get(name) - if page and name not in seen: - ordered.append(page) - seen.add(name) - for name in sorted(pages_by_name): - if name not in seen: - ordered.append(pages_by_name[name]) - return ordered - - -def nav_html(pages: list[DocPage], current_slug: str) -> str: - items: list[str] = [] - for page in pages: - if current_slug == "index": - href = "./" if page.slug == "index" else f"{page.slug}/" - else: - href = "../" if page.slug == "index" else f"../{page.slug}/" - active = ' class="active" aria-current="page"' if page.slug == current_slug else "" - items.append(f'
  • {html.escape(page.title)}
  • ') - return "\n".join(items) - - -def render_page(page: DocPage, pages: list[DocPage]) -> str: - is_index = page.slug == "index" - prefix = "../" if is_index else "../../" - canonical = f"{BASE_URL}docs/" if is_index else f"{BASE_URL}docs/{page.slug}/" - source_url = f"{REPO_URL}/blob/main/docs/{page.source.name}" - body = markdown_to_html(page.source.read_text(encoding="utf-8"), page.slug) - nav = nav_html(pages, page.slug) - structured = { - "@context": "https://schema.org", - "@type": "TechArticle", - "headline": page.title, - "description": page.description, - "url": canonical, - "isPartOf": {"@type": "WebSite", "name": "ARSVIN", "url": BASE_URL}, - "author": {"@type": "Person", "name": "Ari Sulistiono", "url": "https://github.com/masarray"}, - "license": "https://www.apache.org/licenses/LICENSE-2.0", - "about": ["IEC 61850", "Sampled Values", "Digital substation", "Process bus"], - } - json_ld = json.dumps(structured, ensure_ascii=False, separators=(",", ":")) - breadcrumb_label = "Documentation" if is_index else page.title - - return f''' - - - - - {html.escape(page.title)} | ARSVIN Documentation - - - - - - - - - - - - - - - - - - - -
    - - - ARSVIN - - - GitHub -
    - -
    - - - -
    - - - - - -''' - - -def build(repo_root: Path, output: Path) -> None: - site_dir = repo_root / "site" - docs_dir = repo_root / "docs" - if not site_dir.is_dir() or not docs_dir.is_dir(): - raise SystemExit("Expected site/ and docs/ directories under the repository root.") - - if output.exists(): - shutil.rmtree(output) - shutil.copytree(site_dir, output, ignore=shutil.ignore_patterns("docs")) - - docs_output = output / "docs" - docs_output.mkdir(parents=True, exist_ok=True) - - pages_by_name: dict[str, DocPage] = {} - for source in sorted(docs_dir.glob("*.md")): - title, description = page_metadata(source) - slug = "index" if source.name == "index.md" else source.stem - pages_by_name[source.name] = DocPage(source=source, slug=slug, title=title, description=description) - - if "index.md" not in pages_by_name: - raise SystemExit("docs/index.md is required for the documentation site.") - - pages = docs_order(docs_dir, pages_by_name) - for page in pages: - target = docs_output / "index.html" if page.slug == "index" else docs_output / page.slug / "index.html" - target.parent.mkdir(parents=True, exist_ok=True) - target.write_text(render_page(page, pages), encoding="utf-8", newline="\n") - - search_index = [ - { - "title": page.title, - "description": page.description, - "url": "./" if page.slug == "index" else f"{page.slug}/", - "source": page.source.name, - } - for page in pages - ] - (docs_output / "search-index.json").write_text( - json.dumps(search_index, ensure_ascii=False, indent=2) + "\n", encoding="utf-8", newline="\n" - ) - - urls = [BASE_URL] + [BASE_URL + "docs/" if page.slug == "index" else BASE_URL + f"docs/{page.slug}/" for page in pages] - sitemap_lines = [ - '', - '', - ] - for url in urls: - sitemap_lines.extend([" ", f" {html.escape(url)}", " "]) - sitemap_lines.append("") - (output / "sitemap.xml").write_text("\n".join(sitemap_lines) + "\n", encoding="utf-8", newline="\n") - (output / ".nojekyll").write_text("", encoding="utf-8") - print(f"Built public site: {output}") - print(f"Generated documentation pages: {len(pages)}") +from public_site_builder import build def main() -> None: @@ -466,4 +20,4 @@ def main() -> None: if __name__ == "__main__": - main() + main() \ No newline at end of file From 3e5f6299d44b0390dd8ff5afc177fbc0de8a1f91 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:08:10 +0700 Subject: [PATCH 20/69] Package current GPL and commercial licensing documents --- scripts/publish-release.ps1 | 74 +++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/scripts/publish-release.ps1 b/scripts/publish-release.ps1 index 30c1109..6ee0250 100644 --- a/scripts/publish-release.ps1 +++ b/scripts/publish-release.ps1 @@ -29,11 +29,7 @@ $fileVersion = "$coreVersion.0" $informationalVersion = $normalizedVersion function Invoke-DotNet { - param( - [Parameter(Mandatory)] - [string[]] $Arguments - ) - + param([Parameter(Mandatory)][string[]] $Arguments) & dotnet @Arguments if ($LASTEXITCODE -ne 0) { throw "dotnet $($Arguments -join ' ') failed with exit code $LASTEXITCODE." @@ -42,27 +38,49 @@ function Invoke-DotNet { function Reset-Directory { param([Parameter(Mandatory)][string] $Path) - if (Test-Path $Path) { Remove-Item $Path -Recurse -Force } New-Item -ItemType Directory -Path $Path -Force | Out-Null } +function Copy-RequiredFile { + param( + [Parameter(Mandatory)][string] $Source, + [Parameter(Mandatory)][string] $Destination + ) + if (-not (Test-Path $Source -PathType Leaf)) { + throw "Required release document was not found: $Source" + } + Copy-Item $Source $Destination -Force +} + function Copy-ReleaseDocumentation { param([Parameter(Mandatory)][string] $Destination) New-Item -ItemType Directory -Path $Destination -Force | Out-Null - Copy-Item (Join-Path $root 'README.md') (Join-Path $Destination 'README.md') -Force - Copy-Item (Join-Path $root 'LICENSE') (Join-Path $Destination 'LICENSE.txt') -Force - Copy-Item (Join-Path $root 'NOTICE') (Join-Path $Destination 'NOTICE.txt') -Force - Copy-Item (Join-Path $root 'THIRD_PARTY_NOTICES.md') (Join-Path $Destination 'THIRD_PARTY_NOTICES.md') -Force + $rootDocuments = @( + @{ Source = 'README.md'; Destination = 'README.md' }, + @{ Source = 'LICENSE'; Destination = 'LICENSE.txt' }, + @{ Source = 'NOTICE'; Destination = 'NOTICE.txt' }, + @{ Source = 'COMMERCIAL-LICENSE.md'; Destination = 'COMMERCIAL-LICENSE.md' }, + @{ Source = 'COPYRIGHT.md'; Destination = 'COPYRIGHT.md' }, + @{ Source = 'TRADEMARK.md'; Destination = 'TRADEMARK.md' }, + @{ Source = 'THIRD_PARTY_NOTICES.md'; Destination = 'THIRD_PARTY_NOTICES.md' } + ) + + foreach ($document in $rootDocuments) { + Copy-RequiredFile ` + -Source (Join-Path $root $document.Source) ` + -Destination (Join-Path $Destination $document.Destination) + } $docsOut = Join-Path $Destination 'docs' New-Item -ItemType Directory -Path $docsOut -Force | Out-Null $documents = @( + 'LICENSING.md', 'quick-start.md', 'live-mode-safety.md', 'known-limitations.md', @@ -73,7 +91,7 @@ function Copy-ReleaseDocumentation { foreach ($document in $documents) { $source = Join-Path $root "docs\$document" - if (Test-Path $source) { + if (Test-Path $source -PathType Leaf) { Copy-Item $source $docsOut -Force } } @@ -82,6 +100,16 @@ function Copy-ReleaseDocumentation { if (Test-Path $samplesSource) { Copy-Item $samplesSource (Join-Path $Destination 'samples') -Recurse -Force } + + $forbiddenHistoricalLicense = Join-Path $Destination 'LICENSE-APACHE-2.0' + if (Test-Path $forbiddenHistoricalLicense) { + throw "Historical Apache license must not be included in a current GPL release: $forbiddenHistoricalLicense" + } + + $licenseText = Get-Content (Join-Path $Destination 'LICENSE.txt') -Raw + if ($licenseText -notmatch 'GNU GENERAL PUBLIC LICENSE' -or $licenseText -notmatch 'Version 3') { + throw 'Current release LICENSE.txt is not the GNU General Public License version 3 text.' + } } Reset-Directory $releaseRoot @@ -127,19 +155,11 @@ Invoke-DotNet -Arguments (@('publish', $subscriberProject) + $commonPublishArgum $publisherExe = Join-Path $publisherOut 'ARSVIN.exe' $subscriberExe = Join-Path $subscriberOut 'ARSVIN.Subscriber.exe' +if (-not (Test-Path $publisherExe)) { throw "Publisher executable was not found: $publisherExe" } +if (-not (Test-Path $subscriberExe)) { throw "Subscriber executable was not found: $subscriberExe" } -if (-not (Test-Path $publisherExe)) { - throw "Publisher executable was not found: $publisherExe" -} -if (-not (Test-Path $subscriberExe)) { - throw "Subscriber executable was not found: $subscriberExe" -} - -$publisherPortable = Join-Path $releaseRoot 'ARSVIN-Publisher-win-x64.exe' -$subscriberPortable = Join-Path $releaseRoot 'ArSubsv-Subscriber-win-x64.exe' - -Copy-Item $publisherExe $publisherPortable -Force -Copy-Item $subscriberExe $subscriberPortable -Force +Copy-Item $publisherExe (Join-Path $releaseRoot 'ARSVIN-Publisher-win-x64.exe') -Force +Copy-Item $subscriberExe (Join-Path $releaseRoot 'ArSubsv-Subscriber-win-x64.exe') -Force Copy-Item $publisherExe (Join-Path $portableRoot 'ARSVIN.exe') -Force Copy-Item $subscriberExe (Join-Path $portableRoot 'ArSubsv.exe') -Force @@ -155,18 +175,16 @@ Version: $normalizedVersion Runtime: $Runtime Publisher: ARSVIN.exe Subscriber: ArSubsv.exe +Community license: GPL-3.0-or-later +Commercial rights: separate negotiated agreement only "@ Set-Content -Path (Join-Path $portableRoot 'VERSION.txt') -Value $versionFile -Encoding utf8 Set-Content -Path (Join-Path $installerInput 'VERSION.txt') -Value $versionFile -Encoding utf8 $portableZip = Join-Path $releaseRoot 'ARSVIN-win-x64-portable.zip' -if (Test-Path $portableZip) { - Remove-Item $portableZip -Force -} Compress-Archive -Path (Join-Path $portableRoot '*') -DestinationPath $portableZip -CompressionLevel Optimal -Force Write-Host '==> Portable release artifacts' Get-ChildItem $releaseRoot -File | Select-Object Name, Length | Format-Table -AutoSize - Write-Host "Release output: $releaseRoot" -Write-Host "Installer input: $installerInput" +Write-Host "Installer input: $installerInput" \ No newline at end of file From 220284a039132dec414cb702258954759954fff4 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:08:36 +0700 Subject: [PATCH 21/69] Install GPL and commercial licensing documents --- installer/ARSVIN.iss | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/installer/ARSVIN.iss b/installer/ARSVIN.iss index d5164d2..30d1a1d 100644 --- a/installer/ARSVIN.iss +++ b/installer/ARSVIN.iss @@ -58,6 +58,9 @@ Source: "{#SourceDir}\ArSubsv.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "{#SourceDir}\README.md"; DestDir: "{app}"; Flags: ignoreversion Source: "{#SourceDir}\LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion Source: "{#SourceDir}\NOTICE.txt"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#SourceDir}\COMMERCIAL-LICENSE.md"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#SourceDir}\COPYRIGHT.md"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#SourceDir}\TRADEMARK.md"; DestDir: "{app}"; Flags: ignoreversion Source: "{#SourceDir}\THIRD_PARTY_NOTICES.md"; DestDir: "{app}"; Flags: ignoreversion Source: "{#SourceDir}\VERSION.txt"; DestDir: "{app}"; Flags: ignoreversion Source: "{#SourceDir}\docs\*"; DestDir: "{app}\docs"; Flags: ignoreversion recursesubdirs createallsubdirs @@ -67,7 +70,9 @@ Source: "{#SourceDir}\samples\*"; DestDir: "{app}\samples"; Flags: ignoreversion Name: "{group}\ARSVIN Publisher"; Filename: "{app}\ARSVIN.exe"; WorkingDir: "{app}" Name: "{group}\ArSubsv Subscriber"; Filename: "{app}\ArSubsv.exe"; WorkingDir: "{app}" Name: "{group}\Documentation"; Filename: "{app}\README.md" -Name: "{group}\Project website"; Filename: "{#MyAppUrl}" +Name: "{group}\GPL License"; Filename: "{app}\LICENSE.txt" +Name: "{group}\Commercial Licensing Notice"; Filename: "{app}\COMMERCIAL-LICENSE.md" +Name: "{group}\Project website"; Filename: "https://masarray.github.io/arsvin/" Name: "{group}\Uninstall ARSVIN Suite"; Filename: "{uninstallexe}" Name: "{autodesktop}\ARSVIN Publisher"; Filename: "{app}\ARSVIN.exe"; WorkingDir: "{app}"; Tasks: desktopicon @@ -89,10 +94,10 @@ begin SuppressibleMsgBox( 'ARSVIN was installed successfully.' + #13#10 + #13#10 + 'Live IEC 61850 Sampled Values capture and transmission require Npcap. ' + - 'Install Npcap separately from its official website before using live network features.', + 'Install Npcap separately from its official website before using authorized live network features.', mbInformation, MB_OK, IDOK ); end; -end; +end; \ No newline at end of file From b347891cd5779978918daab96f3aaaf7e973918b Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:09:16 +0700 Subject: [PATCH 22/69] Add current-license and public-wording verification --- scripts/verify-current-license.py | 127 ++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 scripts/verify-current-license.py diff --git a/scripts/verify-current-license.py b/scripts/verify-current-license.py new file mode 100644 index 0000000..b8196f4 --- /dev/null +++ b/scripts/verify-current-license.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python3 +"""Verify ARSVIN current licensing, packaging, and public wording boundaries.""" + +from __future__ import annotations + +import re +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] + +REQUIRED_FILES = ( + "LICENSE", + "NOTICE", + "COMMERCIAL-LICENSE.md", + "COPYRIGHT.md", + "TRADEMARK.md", + "CONTRIBUTOR-LICENSE-AGREEMENT.md", + "DCO.txt", + "THIRD_PARTY_NOTICES.md", + "docs/LICENSING.md", + "docs/EXTERNAL_IP_AND_PROVENANCE_REVIEW_2026-07-14.md", + "docs/WORDING_AND_CLAIM_REVIEW_2026-07-14.md", +) + + +def text(relative: str) -> str: + return (ROOT / relative).read_text(encoding="utf-8") + + +def require(condition: bool, message: str, errors: list[str]) -> None: + if not condition: + errors.append(message) + + +def main() -> int: + errors: list[str] = [] + + for relative in REQUIRED_FILES: + require((ROOT / relative).is_file(), f"Missing required licensing or provenance file: {relative}", errors) + + historical_license = ROOT / "LICENSE-APACHE-2.0" + require(not historical_license.exists(), "Current branch must not contain LICENSE-APACHE-2.0", errors) + + license_text = text("LICENSE") + require("GNU GENERAL PUBLIC LICENSE" in license_text, "LICENSE is not the GNU GPL text", errors) + require("Version 3, 29 June 2007" in license_text, "LICENSE does not identify GNU GPL version 3", errors) + require("Apache License" not in license_text, "Current LICENSE contains Apache license wording", errors) + + props = text("Directory.Build.props") + require("GPL-3.0-or-later" in props, + "Directory.Build.props does not declare GPL-3.0-or-later", errors) + require("Apache-2.0" not in props, + "Directory.Build.props still declares Apache-2.0", errors) + + commercial = text("COMMERCIAL-LICENSE.md") + require("not itself a commercial license" in commercial, + "Commercial notice must state that it is not itself a commercial license", errors) + require("grants no additional rights" in commercial, + "Commercial notice must state that it grants no additional rights", errors) + + licensing = text("docs/LICENSING.md") + require("9440f08b6909ef2dc93dd483cfdcb4e1e86077d0" in licensing, + "Licensing document does not record the historical boundary commit", errors) + require("archive/apache-2.0-final" in licensing, + "Licensing document does not identify the historical archive branch", errors) + require("current `main`" in licensing and "GPL-3.0-or-later" in licensing, + "Licensing document does not clearly identify the current GPL branch", errors) + + public_checks = { + "README.md": ( + "license-GPL--3.0--or--later", + "current `main` branch and current public release packages are licensed **only**", + "COMMERCIAL-LICENSE.md", + ), + "site/index.html": ( + '"license": "https://spdx.org/licenses/GPL-3.0-or-later.html"', + "GPL-3.0-or-later", + "Commercial licensing notice", + ), + "NOTICE": ("GPL-3.0-or-later", "archive/apache-2.0-final"), + "scripts/public_site_builder.py": ("GPL-3.0-or-later",), + "scripts/publish-release.ps1": ("COMMERCIAL-LICENSE.md", "LICENSE.txt"), + "installer/ARSVIN.iss": ("COMMERCIAL-LICENSE.md", "GPL License"), + } + for relative, required in public_checks.items(): + value = text(relative) + for marker in required: + require(marker in value, f"{relative} is missing required marker: {marker}", errors) + + stale_patterns = { + "README.md": ( + r"license-Apache--2\.0", + r"focused, Apache-2\.0 engineering suite", + r"Licensed under the \[Apache License 2\.0", + ), + "site/index.html": ( + r'"license"\s*:\s*"https://www\.apache\.org/licenses/LICENSE-2\.0"', + r"Apache-2\.0 · Windows", + r"Apache-2\.0 SV Publisher", + ), + "NOTICE": (r"^Licensed under the Apache License",), + "scripts/public_site_builder.py": (r"Apache-2\.0 engineering documentation",), + "CONTRIBUTING.md": (r"Preserve Apache-2\.0 compatibility",), + } + for relative, patterns in stale_patterns.items(): + value = text(relative) + for pattern in patterns: + require(re.search(pattern, value, flags=re.IGNORECASE | re.MULTILINE) is None, + f"Stale active-license wording in {relative}: {pattern}", errors) + + wording = text("docs/WORDING_AND_CLAIM_REVIEW_2026-07-14.md") + for marker in ("formal conformance", "functional safety", "IED consumed", "guarded live workflow"): + require(marker in wording, f"Public claim review is missing boundary: {marker}", errors) + + if errors: + print("Current-license and public-wording verification failed:", file=sys.stderr) + for error in errors: + print(f"- {error}", file=sys.stderr) + return 1 + + print("Current-license and public-wording verification passed.") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) \ No newline at end of file From f93e69de13a93934b4c73676e245fb467a8d47f3 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:09:51 +0700 Subject: [PATCH 23/69] Run licensing and wording verification before build --- build.ps1 | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/build.ps1 b/build.ps1 index 3506c34..48352be 100644 --- a/build.ps1 +++ b/build.ps1 @@ -8,17 +8,25 @@ $subscriberProject = Join-Path $root 'src\ARSVIN.Subscriber\ARSVIN.Subscriber.cs $testProject = Join-Path $root 'tests\ARSVIN.Tests\ARSVIN.Tests.csproj' function Invoke-DotNet { - param( - [Parameter(Mandatory)] - [string[]] $Arguments - ) - + param([Parameter(Mandatory)][string[]] $Arguments) & dotnet @Arguments if ($LASTEXITCODE -ne 0) { throw "dotnet $($Arguments -join ' ') failed with exit code $LASTEXITCODE." } } +Write-Host '==> Verifying current license, provenance, and public wording' +& python (Join-Path $root 'scripts\verify-current-license.py') +if ($LASTEXITCODE -ne 0) { + throw 'Current-license and public-wording verification failed.' +} + +Write-Host '==> Validating neutral public terminology' +& python (Join-Path $root 'scripts\validate-public-neutrality.py') +if ($LASTEXITCODE -ne 0) { + throw 'Public terminology neutrality validation failed.' +} + Write-Host '==> Restoring locked solution dependency graph' Invoke-DotNet -Arguments @('restore', $solution, '--locked-mode') @@ -31,4 +39,4 @@ Invoke-DotNet -Arguments @('build', $subscriberProject, '-c', 'Release', '--no-r Write-Host '==> Running tests' Invoke-DotNet -Arguments @('test', $testProject, '-c', 'Release', '--no-restore', '/p:TreatWarningsAsErrors=true') -Write-Host '==> Build completed successfully' +Write-Host '==> Build completed successfully' \ No newline at end of file From af873a48a604404b05ef422736bc92d8050eea12 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:10:11 +0700 Subject: [PATCH 24/69] Enforce current licensing and wording in CI --- .github/workflows/ci.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 58d1037..ac5f794 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,12 +12,15 @@ permissions: jobs: public-content: - name: Validate public terminology + name: Validate licensing, provenance, and public wording runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - name: Verify current GPL and commercial-license boundaries + run: python3 scripts/verify-current-license.py + - name: Validate public terminology neutrality id: neutrality continue-on-error: true @@ -54,6 +57,9 @@ jobs: src/**/packages.lock.json tests/**/packages.lock.json + - name: Verify current licensing and public wording + run: python scripts/verify-current-license.py + - name: Build public site and HTML documentation run: python scripts/build-public-site.py --output artifacts/public-site @@ -97,4 +103,4 @@ jobs: run: dotnet list src/ARSVIN/ARSVIN.csproj package --vulnerable --include-transitive - name: Subscriber dependency vulnerability report - run: dotnet list src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj package --vulnerable --include-transitive + run: dotnet list src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj package --vulnerable --include-transitive \ No newline at end of file From fd3ebad791a251e46b043cf8aafe85f2b4795070 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:10:26 +0700 Subject: [PATCH 25/69] Validate licensing before Pages deployment --- .github/workflows/pages.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index fdcaba5..a7f4095 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -6,10 +6,17 @@ on: paths: - 'site/**' - 'docs/**' + - 'README.md' + - 'LICENSE' + - 'NOTICE' + - 'COMMERCIAL-LICENSE.md' + - 'TRADEMARK.md' - 'scripts/build-public-site.py' + - 'scripts/public_site_builder.py' - 'scripts/validate-public-site.ps1' - 'scripts/validate-public-site.py' - 'scripts/validate-public-neutrality.py' + - 'scripts/verify-current-license.py' - '.github/workflows/pages.yml' workflow_dispatch: @@ -32,6 +39,9 @@ jobs: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - name: Verify current GPL and commercial-license boundaries + run: python3 scripts/verify-current-license.py + - name: Validate public terminology neutrality run: python3 scripts/validate-public-neutrality.py @@ -52,4 +62,4 @@ jobs: - name: Deploy id: deployment - uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5 + uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5 \ No newline at end of file From c928b19d0c6cfe67974df300836e1936e90ce8c5 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:11:05 +0700 Subject: [PATCH 26/69] Update web manifest licensing description --- site/site.webmanifest | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/site.webmanifest b/site/site.webmanifest index a303886..5cf37d7 100644 --- a/site/site.webmanifest +++ b/site/site.webmanifest @@ -1,7 +1,7 @@ { "name": "ARSVIN - IEC 61850 Sampled Values Workbench", "short_name": "ARSVIN", - "description": "Apache-2.0 IEC 61850 Sampled Values Publisher and Subscriber suite for Windows with SCL setup, COMTRADE replay, live and PCAP analysis, timing health, and evidence export.", + "description": "GPL-3.0-or-later IEC 61850 Sampled Values Publisher and Subscriber suite for Windows with SCL setup, COMTRADE replay, live and PCAP analysis, timing health, and engineering evidence.", "start_url": "./", "display": "standalone", "background_color": "#f5f8fc", @@ -18,4 +18,4 @@ "type": "image/png" } ] -} +} \ No newline at end of file From 417fd0db34cad5dfb3437a576d87a433925c4a2c Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:11:46 +0700 Subject: [PATCH 27/69] Record GPL and commercial licensing transition --- CHANGELOG.md | 128 +++++++++++++++++++++------------------------------ 1 file changed, 53 insertions(+), 75 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 536ed4b..166c557 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,14 @@ All notable ARSVIN changes are documented here using a lightweight Keep a Change ### Added +- Added the current GPL-3.0-or-later community licensing model and a separate negotiated commercial path. +- Added `COMMERCIAL-LICENSE.md`, `COPYRIGHT.md`, `TRADEMARK.md`, a Contributor License Agreement, and Developer Certificate of Origin. +- Added the historical Apache-2.0 boundary at commit `9440f08b6909ef2dc93dd483cfdcb4e1e86077d0` with preservation branch `archive/apache-2.0-final`. +- Added current-license, packaging, provenance, and public-wording verification to CI, Pages, build, and release paths. +- Added evidence-based external IP/provenance and public-claim reviews. - Added a formal Sampled Values standards and evidence research gate covering authoritative source hierarchy, claim levels, licensed-standard gaps, and implementation acceptance rules. -- Added a conformance and interoperability matrix separating verified, implemented-generic, provisional, unknown, and out-of-scope behavior for Layer-2 SV, 9-2LE-style workflows, IEC 61869-9, timing, scaling, redundancy, and product claims. -- Added a safe Sampled Values evidence-intake guide for anonymized SCL/PCAP cases, real-device metadata, independent verification, minimum negative tests, and evidence quality levels. +- Added a conformance and interoperability matrix separating implemented, provisional, unknown, and out-of-scope behavior for Layer-2 SV, 9-2LE-style workflows, IEC 61869-9, timing, scaling, redundancy, and product claims. +- Added a guarded Sampled Values evidence-intake guide for anonymized or authorized SCL/PCAP cases, device metadata, independent verification, negative tests, and evidence quality levels. - Added transport-independent SV frame observations and an accumulator for stable-field checks, rate estimation, and sample-counter wrap detection. - Added evidence-aware profile definitions with standards-neutral sampling, dataset, packing, payload, and source metadata. - Added an explainable weighted profile detector that reports matches, conflicts, missing evidence, confidence, and score. @@ -18,6 +23,8 @@ All notable ARSVIN changes are documented here using a lightweight Keep a Change ### Changed +- Current README, website, generated documentation, project metadata, installer, and portable packages now identify GPL-3.0-or-later as the only license for later community revisions. +- Release packages include GPL, commercial-licensing notice, copyright, trademark, third-party, and historical-boundary documentation without presenting Apache as a current license choice. - Documentation now prevents unverified profile constants from being promoted directly into production support claims. - Public engineering workflow targets are described generically without proprietary product comparisons or branding. - The built-in profile catalog contains only the generic SCL-driven Layer-2 SV fallback until profile-specific requirements are verified. @@ -27,129 +34,100 @@ All notable ARSVIN changes are documented here using a lightweight Keep a Change - Raised protocol-core coverage from 64.97% to 70.47% and the enforced floor from 60% to 70%. ## 0.4.0 — 2026-07-12 + ### Added - Added a repository-owned, dependency-free public-site builder that converts every `docs/*.md` guide into a dedicated HTML page. - Added compact documentation navigation, topic filtering, breadcrumbs, source links, responsive styling, and a generated search index. - Added unique canonical URLs, descriptions, Open Graph metadata, Twitter Card metadata, and `TechArticle` JSON-LD for engineering documentation pages. - Added a generated multi-page sitemap containing the product homepage and every published documentation page. -- Added recursive validation for all HTML metadata, structured data, canonical uniqueness, local references, search-index targets, sitemap coverage, web-manifest icons, and robots metadata. -- Added committed NuGet lock files for Publisher, Subscriber, the shared engine, and Tests. +- Added recursive validation for HTML metadata, structured data, canonical uniqueness, local references, search-index targets, sitemap coverage, web-manifest icons, and robots metadata. +- Added committed NuGet lock files for Publisher, Subscriber, shared engine, and Tests. - Added CI evidence upload for the committed dependency lock graph. -- Added whole-engine and protocol-core regression floors of 10.5% and 60% respectively. -- Expanded the deterministic test suite from 26 to 54 tests across SCL, COMTRADE, PCAP, MMS, diagnostics, and Sampled Values publisher sessions. +- Expanded deterministic tests across SCL, COMTRADE, PCAP, MMS, diagnostics, and Sampled Values publisher sessions. ### Changed -- GitHub Pages and Windows CI now build and validate the same staged public-site artifact instead of copying raw Markdown into the deployment directory. -- The product landing page now links directly to Quick Start, SV Profile Support, COMTRADE Replay, Subscriber Verification, Safety Boundaries, and the complete documentation index. -- Validated CI, CodeQL, build, test, publish, and release paths now restore NuGet dependencies in locked mode. -- README, build guidance, contributor guidance, repository structure, release examples, and coverage baselines now match the current shared-engine implementation. -- CI, CodeQL, and release validation now use the explicit `windows-2025` runner image; Pages and release publication use `ubuntu-24.04`. -- GitHub Pages now retriggers when the Python public-site validator changes. -- Moved all shared engine source physically from `src/ARSVIN/Engine` into the owning `src/ARSVIN.Engine` project without duplicating compilation. -- Raised whole-engine line coverage from 5.64% to 10.74% and protocol-core coverage from 57.89% to 64.97%. +- GitHub Pages and Windows CI build and validate the same staged public-site artifact. +- The product landing page links directly to Quick Start, SV Profile Support, COMTRADE Replay, Subscriber Verification, Safety Boundaries, and the documentation index. +- Validated CI, CodeQL, build, test, publish, and release paths restore NuGet dependencies in locked mode. +- README, build guidance, contributor guidance, repository structure, release examples, and coverage baselines match the shared-engine implementation. +- CI, CodeQL, and release validation use explicit runner images. +- Shared engine source is physically owned by `src/ARSVIN.Engine` without duplicate compilation. ### Fixed -- Multi-ASDU Publisher sessions now apply the configured `smpCnt` wrap to every ASDU inside a frame, preventing counters such as `4000` and `4001` when a 4,000-sample wrap is configured. +- Multi-ASDU Publisher sessions apply the configured `smpCnt` wrap to every ASDU inside a frame. ### Security -- Published GitHub Releases are now immutable in automation; a release job fails before attestation or upload when the semantic-version tag already has a GitHub Release. -- Artifact corrections require a new semantic-version patch instead of replacing previously published binaries, checksums, or SBOMs. -- Workflow execution no longer depends on moving `windows-latest` or `ubuntu-latest` labels. - -### Planned - -- Continue expanding deterministic regression tests for remaining live capture, MMS service, scheduling, and device-interoperability paths. -- Add Windows Authenticode signing when a trusted certificate becomes available. +- Published GitHub Releases are immutable in automation; corrections require a new semantic-version tag. +- Workflow execution no longer depends on moving default runner labels. ## 0.3.1 — 2026-07-12 ### Added -- Added pinned Coverlet MSBuild instrumentation with TRX, Cobertura, and complete test-log evidence upload. -- Added a verified 50% line-coverage regression floor for the established IEC 61850 protocol-core test surface. -- Added transparent whole-engine coverage reporting: 15,726 production lines at the current 5.64% full-engine baseline. -- Established a protocol-core baseline of 57.89% line coverage across 1,534 instrumented lines, with 888 lines covered and all 26 tests passing. -- Added a repository-owned CycloneDX 1.5 SBOM generator for direct and transitive Publisher/Subscriber NuGet dependencies while excluding test-only packages. -- Added `ARSVIN-SBOM.cdx.json` to validated workflow artifacts, release downloads, and SHA-256 checksums. -- Added signed GitHub build-provenance and SBOM attestations for tagged release artifacts. -- Added the shared `ARSVIN.Engine` class library as the single compiled IEC 61850 protocol implementation used by Publisher, Subscriber, and Tests. +- Added Coverlet MSBuild instrumentation with TRX, Cobertura, and complete test-log evidence upload. +- Added whole-engine and protocol-core coverage reporting and enforcement. +- Added a repository-owned CycloneDX 1.5 SBOM generator for direct and transitive runtime dependencies. +- Added `ARSVIN-SBOM.cdx.json` to workflow artifacts, releases, and SHA-256 checksums. +- Added GitHub build-provenance and SBOM attestations for tagged release artifacts. +- Added `ARSVIN.Engine` as the single compiled IEC 61850 implementation used by Publisher, Subscriber, and Tests. ### Changed -- Public releases now require semantic-version tags whose commits are already contained in `main`. -- Alpha, beta, and release-candidate tags are published as prereleases without replacing the latest stable release. -- Centralized Publisher and Subscriber source version metadata. -- GitHub Pages now validates the public site immediately before deployment. -- Publisher and Subscriber now reference one engine assembly instead of compiling duplicate copies of the protocol source. -- Protocol tests now exercise the same `ARSVIN.Engine` assembly shipped with both applications. -- Coverage instrumentation now measures the complete shared engine while preserving the tested protocol-core regression gate. +- Public releases require semantic-version tags whose commits are contained in `main`. +- Prerelease tags do not replace the latest stable release. +- Publisher and Subscriber reference one engine assembly. +- Protocol tests exercise the same engine assembly shipped with both applications. ### Security -- Pinned all GitHub Actions used by CI, CodeQL, Pages, and release workflows to immutable commit SHAs while retaining version comments for maintainability and Dependabot updates. -- Pinned automated installer compilation to the exact Inno Setup 6.7.1 Chocolatey package and retained resolved compiler metadata in workflow evidence. -- Treat compiler warnings as errors in validated Publisher, Subscriber, test, release, and CodeQL build paths. -- Stabilized SBOM component ordering, source commit, and metadata timestamp for repeatable review from the same commit. +- Pinned GitHub Actions to immutable commit SHAs. +- Pinned automated installer compilation to a reviewed Inno Setup package version. +- Treat compiler warnings as errors in validated build paths. +- Stabilized SBOM ordering, source commit, and metadata timestamp for repeatable review. ## 0.3.0 — 2026-07-11 ### Added -- Public Apache-2.0 ARSVIN suite positioning with separate Publisher and ArSubsv Subscriber applications. -- Self-contained Windows x64 portable executables for Publisher and Subscriber. -- Inno Setup suite installer with Start Menu shortcuts, documentation, samples, and uninstaller. -- Portable suite ZIP and SHA-256 checksum release assets. -- SCL/SCD-assisted SV stream configuration and validation. -- Multi-ASDU Sampled Values publishing with `nofASDU=1/2/4/8`. -- Manual values, ramps, state sequences, per-phase scenarios, waveform shaping, and COMTRADE replay. -- Publisher timing-health metrics, generated PCAP export, and Markdown evidence reports. -- ArSubsv live Npcap capture, classic-PCAP import, stream discovery, payload decoding, waveform, phasor, RMS, and receiver reports. -- Real application screenshots in the public README and GitHub Pages product site. -- SEO metadata, Open Graph, Twitter Card, `SoftwareApplication` JSON-LD, FAQ structured data, sitemap, robots, and web manifest. -- GitHub Actions CI, full-solution CodeQL, Pages deployment, release packaging, installer smoke test, and dependency vulnerability reports. +- Public Apache-2.0 ARSVIN suite release with separate Publisher and ArSubsv Subscriber applications. +- Self-contained Windows x64 portable executables, suite installer, portable ZIP, and SHA-256 checksums. +- SCL/SCD-assisted SV configuration, multi-ASDU publishing, scenarios, waveform shaping, and COMTRADE replay. +- Publisher timing-health metrics, PCAP export, and Markdown evidence reports. +- ArSubsv live capture, PCAP import, stream discovery, payload decoding, waveform, phasor, RMS, and receiver reports. +- Actual application screenshots, SEO metadata, structured data, sitemap, robots, web manifest, CI, CodeQL, Pages, and release automation. ### Changed -- Reworked ArSubsv into a compact engineering workspace with a persistent stream explorer, dominant waveform view, phasor rail, values, frame details, diagnostics, and cursor comparison. -- Normalized Subscriber phasor angles to `Va = 0°` for clearer Publisher/Subscriber comparison. -- Centralized public documentation around transparent laboratory evidence and explicit IEC 61850 safety boundaries. -- Made silent installer and uninstaller operation suitable for automated release validation. +- Reworked ArSubsv into a compact engineering workspace. +- Normalized Subscriber phasor angles to `Va = 0°` for Publisher/Subscriber comparison. +- Centralized public documentation around laboratory evidence and explicit operational boundaries. ### Fixed -- Publisher shutdown dispatch no longer raises late UI exceptions while the application is closing. -- Subscriber payload decoding, linked engine compilation, WPF control resolution, and frame parser build issues. -- Publisher slot selection now updates the currently selected live slot instead of a stale startup selection. -- Release packaging now fails immediately when external `dotnet` or installer commands fail. +- Publisher shutdown dispatch, Subscriber payload decoding, linked engine compilation, WPF control resolution, frame parser, slot selection, and release-command handling issues. -### Safety +### Operational boundary -- Clarified that ARSVIN is not a calibrated protection test set, certified merging unit, deterministic real-time platform, production process-bus monitor, or IEC 61850 conformance tool. -- Clarified that Publisher evidence proves generated traffic and Subscriber evidence proves PC/NIC reception, not IED consumption. -- Kept Npcap external to the installer and limited live use to authorized, isolated laboratory networks. +- Clarified that ARSVIN is not calibrated, deterministic real-time, production-monitoring, or formal conformance equipment. +- Clarified that Publisher and Subscriber evidence does not prove IED consumption. +- Kept Npcap external to the installer and limited live use to authorized isolated test networks. ## 0.2.0 — 2026-07-02 ### Added -- Initial ArSubsv IEC 61850 Sampled Values Subscriber companion. -- Npcap capture, SV APDU decode, SCL binding, stream-health analysis, sample-counter continuity checks, decoded values, waveform, phasor, RMS, PCAP replay, and Markdown verification reports. +- Initial ArSubsv Subscriber companion with Npcap capture, SV decode, SCL binding, stream health, values, waveform, phasor, RMS, PCAP replay, and reports. ### Changed -- Kept Publisher and Subscriber as separate applications so each workflow remains focused and its evidence boundary remains clear. +- Kept Publisher and Subscriber separate so each evidence boundary remains explicit. ## 0.1.0 — 2026-06-01 ### Added -- Initial Windows WPF IEC 61850 Sampled Values Publisher. -- SCL-based stream setup. -- Manual, ramp, and state-sequenced publishing workflows. -- COMTRADE replay. -- Laboratory PTP and `smpSynch` compatibility controls. -- Initial CI, CodeQL, Pages, and release packaging. +- Initial Windows WPF Sampled Values Publisher with SCL setup, manual and sequenced publishing, COMTRADE replay, laboratory timing controls, CI, Pages, and release packaging. \ No newline at end of file From 1d08e97c5e948cd5fdbd2d7af4721b7926d904ff Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:12:23 +0700 Subject: [PATCH 28/69] Refresh repository audit after licensing migration --- docs/repository-audit.md | 54 +++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/docs/repository-audit.md b/docs/repository-audit.md index c6c31a4..69b6383 100644 --- a/docs/repository-audit.md +++ b/docs/repository-audit.md @@ -1,38 +1,42 @@ # Repository Audit -Audit date: 2026-06-30 +Audit refreshed: 2026-07-14 ## Summary -ARSVIN already has a strong public-repository foundation: focused README, engineering docs, Apache-2.0 intent, GitHub Actions CI, CodeQL, Dependabot, release packaging, and a GitHub Pages landing page. +ARSVIN now has a professional public-repository foundation for an IEC 61850 Sampled Values engineering suite: -The main gaps before calling it a polished global open-source repository were: - -- License text needed the full Apache-2.0 appendix / application notice. -- No issue templates or pull request template. -- No unit test project. -- Architecture documentation was not explicit enough for external contributors. -- Third-party dependency notices were not listed separately. -- Release readiness checklist was missing. +- GPL-3.0-or-later current community edition; +- separate negotiated commercial licensing path; +- preserved historical Apache-2.0 boundary; +- Publisher, Subscriber, and shared-engine architecture; +- deterministic tests and coverage gates; +- locked dependencies, vulnerability reporting, SBOM, checksums, and artifact attestations; +- CI, CodeQL, Pages, installer, and immutable release automation; +- structured issue and pull-request workflows; +- SEO-ready product site and searchable documentation; and +- operational, provenance, wording, and external-material controls. ## Current strengths -- Clear niche: IEC 61850 Sampled Values lab publishing. -- Honest safety positioning: not a certified protection test set. -- Existing docs for quick start, live safety, PTP/smpSynch, COMTRADE, and limitations. -- CI, CodeQL, release workflow, Pages workflow, and Dependabot already present. -- No obvious committed secrets found during static text scan. +- Clear scope: Sampled Values generation, reception, decoding, visualization, diagnostics, and evidence. +- Explicit distinction between transmitter evidence, receiver evidence, and IED behavior. +- Current-license and public-wording verification before build, Pages deployment, and release packaging. +- Separate Publisher and Subscriber applications using one shared engine. +- Release artifacts include current license, commercial notice, copyright, trademark, and third-party notices. +- Public fixtures are expected to be synthetic or documented as authorized and sanitized. +- Current claims avoid formal conformance, calibrated measurement, deterministic timing, functional-safety, cybersecurity, and IED-consumption guarantees. + +## Remaining priorities -## High-priority recommendations +1. Expand deterministic coverage for live transport, scheduling, MMS/SCL edge cases, malformed traffic, and device-interoperability paths. +2. Add additional independently sourced packet fixtures with documented provenance. +3. Add Authenticode signing when a suitable certificate and operational process are available. +4. Maintain evidence labels that distinguish automated tests, loopback, laboratory devices, and approved commissioning environments. +5. Perform a contributor, employment, invention-assignment, confidentiality, trademark, and private-artifact review before a high-value commercial agreement. -1. Split pure IEC 61850 protocol code into a class library once the API stabilizes. -2. Add more tests around SCL parsing, SV frame encoding, COMTRADE reading, VLAN behavior, and PTP compatibility. -3. Add golden packet fixtures for SV and PTP behavior. -4. Keep safety language prominent in README, docs, and release notes. -5. Avoid marketing claims such as “certified,” “calibrated,” or “real-time accurate” unless independently validated. +## Scope limitations -## Public readiness score +Repository inspection cannot prove ownership of every off-repository artifact or resolve employment and contractual obligations. Git account attribution is evidence of activity, not by itself conclusive legal ownership. -- Before cleanup: 7.8 / 10 -- After repository-polish cleanup: 8.8 / 10 -- To reach 9.5+ global standard: separate engine library, test coverage, signed releases, SBOM/provenance, and packet-level golden fixtures. +See [External IP and Provenance Review](EXTERNAL_IP_AND_PROVENANCE_REVIEW_2026-07-14.md), [Public Wording and Claim Review](WORDING_AND_CLAIM_REVIEW_2026-07-14.md), and [Licensing](LICENSING.md). \ No newline at end of file From 5cf254617129fb5f2755a56ae50f7530556d1bd7 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:12:55 +0700 Subject: [PATCH 29/69] Update release checklist for current GPL packages --- docs/public-release-checklist.md | 67 +++++++++++++++++--------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/docs/public-release-checklist.md b/docs/public-release-checklist.md index 54b52fd..c0f05f1 100644 --- a/docs/public-release-checklist.md +++ b/docs/public-release-checklist.md @@ -2,47 +2,50 @@ Use this checklist before making a public GitHub release. -## Repository health - -- [ ] README explains purpose, scope, install, build, and safety boundaries. -- [ ] LICENSE contains the Apache License 2.0 text. -- [ ] NOTICE and third-party notices are current. +## Repository and licensing health + +- [ ] README explains purpose, scope, installation, build, operational boundaries, evidence limits, and licensing. +- [ ] `LICENSE` contains the GNU General Public License version 3 text. +- [ ] `Directory.Build.props` declares `GPL-3.0-or-later`. +- [ ] Current source and release wording do not present Apache-2.0 as an active alternative license. +- [ ] The historical boundary commit and `archive/apache-2.0-final` branch are documented. +- [ ] `COMMERCIAL-LICENSE.md` states that it is an invitation to negotiate and grants no additional rights by itself. +- [ ] NOTICE, copyright, trademark, and third-party notices are current. +- [ ] CLA and DCO contribution gates are present. - [ ] CONTRIBUTING, SECURITY, SUPPORT, and CODE_OF_CONDUCT are present. -- [ ] GitHub topics are set. -- [ ] Repository description is concise and searchable. -- [ ] GitHub Pages link is enabled if the landing page is used. +- [ ] Current-license, provenance, terminology, and public-wording validators pass. +- [ ] Repository description, topics, and Pages URL are current and searchable. ## Engineering quality -- [ ] `dotnet restore` succeeds. -- [ ] warning-free `dotnet build -c Release -warnaserror` succeeds on Windows. -- [ ] unit tests succeed. -- [ ] the configured line-coverage regression floor succeeds. +- [ ] Locked `dotnet restore` succeeds. +- [ ] Warning-free Release builds succeed for Publisher and Subscriber. +- [ ] Deterministic tests and configured coverage gates succeed. - [ ] TRX and Cobertura evidence are retained by CI. -- [ ] CodeQL workflow passes. -- [ ] dependency vulnerability reports pass. -- [ ] Dependabot is enabled for NuGet and GitHub Actions. -- [ ] no secrets, real station files, private captures, or confidential SCL files are committed. +- [ ] CodeQL and dependency vulnerability workflows pass. +- [ ] Dependency lock files and SBOM inputs are reviewed. +- [ ] No credentials, customer data, station files, restricted addressing, production captures, confidential SCL, or proprietary third-party material are committed. +- [ ] Every non-synthetic fixture has documented authority, sanitization, and provenance. -## Safety +## Operational and claim boundary -- [ ] README warns that ARSVIN can transmit raw Ethernet frames. -- [ ] live mode safety docs are up to date. -- [ ] known limitations are honest and visible. -- [ ] release notes state that the app is not a certified protection test set. -- [ ] testers use isolated lab networks or point-to-point links. +- [ ] README and installer state that ARSVIN can transmit and capture raw Ethernet frames. +- [ ] Live features are limited to authorized test networks and approved workflows. +- [ ] Known limitations and evidence boundaries are visible. +- [ ] Release notes do not imply formal conformance, calibration, deterministic timing, functional safety, cybersecurity approval, switching authority, or IED consumption proof. +- [ ] Validation sources are identified as automated tests, loopback, simulator, laboratory equipment, or approved commissioning evidence. ## Release package -- [ ] tag format is `vX.Y.Z` or a valid semantic-version prerelease. -- [ ] tagged commit is already contained in protected `main`. -- [ ] Publisher portable EXE exists and is non-empty. -- [ ] Subscriber portable EXE exists and is non-empty. -- [ ] suite installer exists and passes silent install/uninstall smoke testing. -- [ ] portable ZIP includes executables, README, LICENSE, notices, and relevant docs. -- [ ] CycloneDX SBOM exists, parses, and contains resolved dependency components. -- [ ] SHA-256 checksum file covers all distributed release assets. +- [ ] Tag format is `vX.Y.Z` or a valid semantic-version prerelease. +- [ ] Tagged commit is already contained in protected `main`. +- [ ] Publisher and Subscriber portable EXEs exist and are non-empty. +- [ ] Suite installer passes silent install and uninstall smoke testing. +- [ ] Portable ZIP and installer include `LICENSE.txt`, `NOTICE.txt`, `COMMERCIAL-LICENSE.md`, `COPYRIGHT.md`, `TRADEMARK.md`, `THIRD_PARTY_NOTICES.md`, and `docs/LICENSING.md`. +- [ ] No historical Apache license file is included in a current GPL package. +- [ ] CycloneDX SBOM parses and contains resolved runtime dependency components. +- [ ] SHA-256 checksums cover every distributed release asset. - [ ] GitHub build-provenance and SBOM attestations are created for tagged assets. - [ ] `gh attestation verify` succeeds for a downloaded release file. -- [ ] release notes include highlights, fixes, known limitations, and safety reminders. -- [ ] downloaded artifacts run on a clean Windows machine with Npcap installed for live-network testing. +- [ ] Release notes include highlights, fixes, known limitations, licensing, and operational reminders. +- [ ] Downloaded artifacts run on a clean Windows machine; Npcap is installed separately only for authorized live-network testing. \ No newline at end of file From fdda37a62fac7531b901f3d64cf43246c598cc9c Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:13:27 +0700 Subject: [PATCH 30/69] Update SEO launch guidance for current licensing and scope --- docs/seo-public-launch-checklist.md | 116 ++++++++++++++-------------- 1 file changed, 56 insertions(+), 60 deletions(-) diff --git a/docs/seo-public-launch-checklist.md b/docs/seo-public-launch-checklist.md index 3d97598..3160349 100644 --- a/docs/seo-public-launch-checklist.md +++ b/docs/seo-public-launch-checklist.md @@ -1,124 +1,120 @@ # SEO and Public Launch Checklist -This checklist keeps ARSVIN discoverable and trustworthy as a public Apache-2.0 engineering repository. +This checklist keeps ARSVIN discoverable and trustworthy as a GPL-3.0-or-later IEC 61850 Sampled Values engineering repository with a separate commercial licensing path. ## Target positioning -Primary phrase: +Primary phrases: ```text -IEC 61850 Sampled Values Publisher for Windows +IEC 61850 Sampled Values Publisher and Subscriber for Windows +IEC 61850 Sampled Values engineering workbench ``` Secondary phrases: ```text IEC 61850 SV Publisher -Sampled Values Publisher -SV Injector -Merging Unit Simulator -IEC 61850 Process Bus Tool +Sampled Values Subscriber +SV stream analyzer COMTRADE to Sampled Values SCL-driven SV Publisher +PCAP Sampled Values analysis +process bus engineering software +Sampled Values waveform phasor RMS ``` -Use these phrases naturally in the README, landing page, release notes, and documentation. Avoid claiming certified conformance unless formal testing has been completed. +Use phrases naturally. Do not use “injector,” “merging unit simulator,” “certified,” “conformant,” “real-time accurate,” or similar wording as an unqualified product claim when it could imply calibrated equipment, formal conformance, or deterministic execution. ## GitHub repository settings -- Set repository description to: +Recommended repository description: ```text -Apache-2.0 IEC 61850 Sampled Values Publisher for Windows — SCL-driven SV publishing, COMTRADE replay, nofASDU support, TX timing health, scenario presets, and PCAP evidence export. +GPL IEC 61850 Sampled Values Publisher and Subscriber for Windows — SCL setup, COMTRADE replay, live/PCAP analysis, waveform, phasor, RMS, timing health, and engineering evidence. ``` -- Set website URL to: +Website URL: ```text https://masarray.github.io/arsvin/ ``` -- Add topics: +Recommended topics: ```text iec61850 iec-61850 sampled-values sampled-values-publisher +sampled-values-subscriber sv-publisher -sv-injector -merging-unit -merging-unit-simulator process-bus digital-substation substation-automation comtrade -ptp +pcap +phasor +waveform wpf dotnet windows +gplv3 ``` - Upload `site/assets/arsvin-social-preview.png` as the GitHub social preview image. -- Enable GitHub Pages using the existing Pages workflow. -- Use Releases for portable downloads. -- Pin or link the latest stable release in the README and landing page. +- Enable GitHub Pages using the reviewed Actions workflow. +- Use immutable Releases for downloadable artifacts. +- Link the latest stable release from README and landing page. ## README requirements -- Product title contains the primary phrase. -- First paragraph explains what ARSVIN is, who it is for, and the main workflow. -- A preview image appears near the top. -- Download, landing page, quick start, and docs links are visible above the fold. -- Safety boundaries are visible before the quick start. -- Feature matrix includes `nofASDU`, SCL, COMTRADE, TX Timing Health, PCAP, report, and scenarios. -- “What ARSVIN is not” is explicit and honest. +- Product title and opening paragraph state Publisher, Subscriber, Windows, and IEC 61850 Sampled Values. +- Download, website, quick start, documentation, and licensing links are visible near the top. +- Actual application images have descriptive alternative text. +- Operational boundaries are visible before live-network instructions. +- Capabilities include SCL, COMTRADE, `nofASDU`, timing health, PCAP, reports, waveform, phasor, RMS, and scenarios. +- Transmitter evidence, receiver evidence, and IED behavior are clearly separated. +- GPL-3.0-or-later is the only current community license shown. +- The commercial notice is described as a separate negotiated path, not an automatically granted alternative license. ## Landing page requirements -- Title: `ARSVIN — IEC 61850 Sampled Values Publisher for Windows`. -- H1 uses the primary phrase. -- Meta description stays specific and non-generic. -- Open Graph image points to `arsvin-social-preview.png`. -- FAQ section answers common search questions. -- SoftwareApplication and FAQ structured data are present. -- Safety boundaries are visible without needing to open the README. +- Unique title and meta description include IEC 61850 Sampled Values and the actual Publisher/Subscriber scope. +- Exactly one H1 describes the engineering workflow without exaggerated claims. +- Open Graph and Twitter images use the project-owned social preview. +- `SoftwareApplication` JSON-LD declares `GPL-3.0-or-later`. +- FAQ structured data covers Npcap, evidence limits, formal conformance, and commercial licensing. +- Canonical URL, sitemap, robots metadata, manifest, and descriptive image alt text are present. +- Operational and licensing boundaries are visible without opening another page. -## Image SEO +## Documentation SEO -Use descriptive file names and alt text: - -```text -arsvin-iec-61850-sampled-values-publisher-preview.png -arsvin-social-preview.png -``` - -Alt text should describe the product and the visible workflow, for example: - -```text -ARSVIN IEC 61850 Sampled Values Publisher preview with SCL setup, TX Timing Health, nofASDU, COMTRADE replay, PCAP evidence, and scenario presets -``` +- Every published guide has a unique title, description, canonical URL, and `TechArticle` structured data. +- Sitemap includes the product homepage and every generated documentation page. +- Documentation links use stable paths and no broken local references. +- Current docs do not present Apache-2.0 as an active license; historical references are clearly labelled and link to the archive boundary. +- External product names are not used as feature-target or affiliation keywords. ## Release SEO Each public release should include: -- short summary of user-facing changes, -- portable ZIP asset name, -- upgrade notes, -- known limitations, -- safety reminder, -- screenshot or link to the landing page. +- a concise user-facing summary; +- stable artifact names; +- upgrade and compatibility notes; +- known limitations and evidence boundaries; +- current GPL and separate commercial-path wording; +- operational reminder for authorized live Ethernet use; and +- a screenshot or product-site link. ## Trust evidence Keep these visible: -- Apache-2.0 license, -- CI badge, -- CodeQL badge, -- SECURITY.md, -- CONTRIBUTING.md, -- sample SCL and COMTRADE files, -- sample evidence report, -- generated PCAP workflow. +- GPL-3.0-or-later license badge and full license text; +- commercial licensing notice; +- CI, CodeQL, Pages, release, SBOM, checksum, and attestation evidence; +- SECURITY, SUPPORT, CONTRIBUTING, CLA, DCO, copyright, trademark, and third-party notices; +- synthetic or authorized sample SCL, COMTRADE, PCAP, and report evidence; and +- explicit limitations concerning calibration, timing, formal conformance, cybersecurity, functional safety, and IED consumption. \ No newline at end of file From 47f5c8e21358a7065669592b0477f53339184caf Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:13:57 +0700 Subject: [PATCH 31/69] Update recommended GitHub metadata for GPL licensing --- docs/github-repository-settings.md | 67 ++++++++++++++++-------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/docs/github-repository-settings.md b/docs/github-repository-settings.md index 1a0f923..4172426 100644 --- a/docs/github-repository-settings.md +++ b/docs/github-repository-settings.md @@ -1,17 +1,17 @@ # GitHub Repository Settings -These settings are stored in GitHub rather than the source tree. Apply them manually after the pull request is merged. +These settings are stored in GitHub rather than the source tree. Review them after merging licensing or public-positioning changes. ## Repository visibility -Set the repository to **Public**. The repository is already public as of July 11, 2026. +The repository is public. Keep public visibility only while the current GPL source, required notices, and corresponding release source remain available. ## About panel -Description: +Recommended description: ```text -Apache-2.0 IEC 61850 Sampled Values workbench for Windows — SCL-driven SV publishing, COMTRADE replay, live/PCAP subscriber analysis, waveform, phasor, RMS, timing health, and evidence export. +GPL IEC 61850 Sampled Values Publisher and Subscriber for Windows — SCL setup, COMTRADE replay, live/PCAP analysis, waveform, phasor, RMS, timing health, and engineering evidence. ``` Website: @@ -20,14 +20,9 @@ Website: https://masarray.github.io/arsvin/ ``` -Enable: +Enable Releases and Issues. Enable Discussions only when maintainer capacity supports moderation and technical follow-up. -- Releases -- Packages only when a package feed is introduced -- Issues -- Discussions only when there is enough maintainer capacity - -Topics: +Recommended topics: ```text iec61850 @@ -37,19 +32,20 @@ sampled-values-publisher sampled-values-subscriber sv-publisher sv-subscriber -sv-injector process-bus digital-substation substation-automation comtrade pcap phasor +waveform wpf dotnet windows +gplv3 ``` -Avoid topics that imply certification, calibration, deterministic real-time performance, or affiliation with another vendor. +Avoid topics that imply certification, calibration, deterministic real-time performance, functional safety, cybersecurity approval, or affiliation with another organization. ## Social preview @@ -68,13 +64,13 @@ Publisher • Subscriber • SCL • COMTRADE • PCAP • Engineering Evidence ## Pages -Use **GitHub Actions** as the Pages source. The existing workflow is: +Use **GitHub Actions** as the Pages source: ```text .github/workflows/pages.yml ``` -Expected public URL: +Expected URL: ```text https://masarray.github.io/arsvin/ @@ -82,38 +78,45 @@ https://masarray.github.io/arsvin/ After deployment, verify: -- canonical URL, -- responsive layout, -- Open Graph preview, -- direct latest-release links, -- `robots.txt`, -- `sitemap.xml`. +- canonical URL, responsive layout, and accessible navigation; +- Open Graph and Twitter preview; +- GPL-3.0-or-later JSON-LD and visible licensing section; +- separate commercial-path wording that does not imply automatic extra rights; +- direct latest-release links; +- generated documentation and search index; +- `robots.txt` and `sitemap.xml`; and +- no stale active Apache-2.0 metadata. ## Releases -The release workflow publishes stable asset names: +Stable asset names: ```text ARSVIN-Publisher-win-x64.exe ArSubsv-Subscriber-win-x64.exe ARSVIN-Suite-Setup-win-x64.exe ARSVIN-win-x64-portable.zip +ARSVIN-SBOM.cdx.json SHA256SUMS.txt ``` Release notes should include: -- Publisher and Subscriber capability summary, -- installer and portable usage, -- Npcap requirement for live workflows, -- unsigned-binary/SmartScreen note, -- safety warning, -- known limitations, -- link to documentation. +- Publisher and Subscriber capability summary; +- installer and portable usage; +- Npcap requirement for authorized live workflows; +- unsigned-binary and SmartScreen note; +- operational and evidence boundaries; +- GPL community licensing and separate commercial path; +- known limitations; and +- documentation link. + +Current packages must include GPL, NOTICE, commercial notice, copyright, trademark, third-party notices, and `docs/LICENSING.md`. They must not include a historical Apache license file as though it applied to current binaries. ## Recommended merge settings - Enable squash merge. -- Automatically delete head branches after merge. -- Require the CI and CodeQL checks before merging into `main` when branch protection is enabled. -- Require pull requests for changes to `main` when the project begins accepting external contributors. +- Automatically delete merged head branches. +- Require CI, CodeQL, current-license, Pages validation, and release validation where applicable. +- Require pull requests for changes to `main` when accepting external contributors. +- Require CLA affirmation and DCO sign-off for external contributions. \ No newline at end of file From a49ec76def270dd123bfbb0d244f2573f88dd394 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:14:46 +0700 Subject: [PATCH 32/69] Update build and release guide for GPL packages --- docs/build-and-release.md | 267 ++++++++++++++------------------------ 1 file changed, 96 insertions(+), 171 deletions(-) diff --git a/docs/build-and-release.md b/docs/build-and-release.md index c19b17e..0685ad2 100644 --- a/docs/build-and-release.md +++ b/docs/build-and-release.md @@ -1,39 +1,48 @@ # Build and Release -ARSVIN uses a tag-driven GitHub Actions workflow to build two self-contained portable applications, one suite installer, one portable ZIP, a CycloneDX software bill of materials, SHA-256 checksums, and signed GitHub artifact attestations. +ARSVIN uses tag-driven GitHub Actions to build two self-contained applications, a suite installer, a portable ZIP, a CycloneDX SBOM, SHA-256 checksums, and GitHub artifact attestations. ## Prerequisites -For local source builds: +Local source builds require Windows 10 or Windows 11 x64, .NET 8 SDK feature band 8.0.4xx, and PowerShell 7+ recommended. Reproducing the installer also requires Inno Setup 6.7.1. -- Windows 10/11 x64 -- .NET 8 SDK, feature band 8.0.4xx -- PowerShell 7+ recommended +Npcap is required only for authorized live capture or transmission tests. It is not bundled or silently installed. -For local installer builds: +## Licensing and public-content gate -- All requirements above -- Inno Setup 6.7.1 +Before restore, build, site publication, or release packaging, run: -Npcap is required only for live capture/transmission testing. It is not silently bundled or installed by the ARSVIN release process. +```powershell +python scripts/verify-current-license.py +python scripts/validate-public-neutrality.py +``` -## Dependency locking +The first command verifies: -Package versions are centrally managed in `Directory.Packages.props`. Each project commits a `packages.lock.json` file so the resolved direct and transitive NuGet graph is reviewable and repeatable. +- GNU GPL version 3 as the current root license; +- `GPL-3.0-or-later` project metadata; +- historical Apache boundary documentation without an active dual-license presentation; +- commercial-notice wording that grants no rights by itself; +- required copyright, trademark, CLA, DCO, provenance, and third-party files; and +- current README, site, installer, and packaging markers. + +The second command rejects prohibited external-product comparison terms from public content. + +## Dependency locking -Validated automation restores with locked mode: +Package versions are centrally managed in `Directory.Packages.props`. Every project commits `packages.lock.json` so the resolved graph is reviewable and reproducible. ```powershell dotnet restore ARSVIN.sln --locked-mode ``` -A dependency update must intentionally regenerate the affected lock files and include them in the same pull request: +A deliberate dependency update uses: ```powershell dotnet restore ARSVIN.sln --force-evaluate ``` -Do not hand-edit lock files. Review dependency and integrity changes in the generated diff. +Review direct and transitive changes, licenses, vulnerability output, and lock-file integrity. Do not hand-edit lock files. ## Build and test @@ -41,91 +50,49 @@ Do not hand-edit lock files. Review dependency and integrity changes in the gene .\build.ps1 ``` -The script restores the solution in locked mode, then builds and tests: +The build script: -- `src/ARSVIN.Engine/ARSVIN.Engine.csproj` -- `src/ARSVIN/ARSVIN.csproj` -- `src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj` -- `tests/ARSVIN.Tests/ARSVIN.Tests.csproj` +1. verifies current licensing, provenance, and public wording; +2. validates public terminology neutrality; +3. restores the locked dependency graph; +4. builds Publisher and Subscriber with warnings as errors; and +5. runs deterministic tests. -The shared production source is physically owned by `src/ARSVIN.Engine`, including IEC 61850 protocol code, Sampled Values profile infrastructure, and the Npcap transport implementation. Publisher, Subscriber, and Tests reference the same compiled assembly. +Publisher, Subscriber, and Tests reference the same `ARSVIN.Engine` assembly. Protocol parsing, Sampled Values behavior, SCL handling, profile observations, comparison logic, capture, and transport code remain owned by the shared engine project. -External command exit codes are checked, and compiler warnings are treated as errors for the validated build path. - -### Coverage evidence +## Coverage evidence ```powershell .\scripts\test-with-coverage.ps1 -MinimumWholeEngineLineCoverage 13 -MinimumLineCoverage 70 ``` -The script: - -1. runs the xUnit suite using pinned Coverlet MSBuild instrumentation, -2. instruments the complete shared production `ARSVIN.Engine` assembly, -3. writes TRX, the complete `dotnet test` log, and Cobertura evidence under `artifacts/test-results`, -4. calculates and enforces the whole-engine regression floor, -5. calculates and enforces the protocol-core regression floor, -6. fails when no production lines are instrumented or either configured floor is missed. - -Current verified baselines from 74 deterministic tests: - -| Metric | Result | -|---|---:| -| Whole `ARSVIN.Engine` instrumented lines | 16,312 | -| Whole-engine covered lines | 2,178 | -| Whole-engine line coverage | 13.35% | -| Enforced whole-engine floor | 13% | -| Protocol-core instrumented lines | 2,120 | -| Protocol-core covered lines | 1,494 | -| Protocol-core line coverage | 70.47% | -| Enforced protocol-core floor | 70% | +The coverage workflow retains TRX, full test logs, and Cobertura output under `artifacts/test-results`, then enforces whole-engine and protocol-core regression floors. -The suite covers deterministic behavior across Sampled Values framing, publisher sessions, profile observations, evidence-aware detection, configuration comparison, SCL parsing, COMTRADE parsing and scaling, PCAP read/write handling, MMS data and object references, diagnostics, Ethernet framing, and transport helpers. It does not claim complete WPF, live-network, timing, or device-interoperability coverage. +The documented baseline contains 74 deterministic tests, 13.35% whole-engine line coverage, and 70.47% protocol-core line coverage. These values are regression evidence, not formal conformance, complete live-network validation, deterministic timing evidence, or universal device-interoperability evidence. -## Validate public content - -Public documentation uses neutral engineering terminology and avoids proprietary comparison language. - -```powershell -python scripts/validate-public-neutrality.py -``` - -CI and Pages deployment run this check before publishing public content. The validator writes evidence to: - -```text -artifacts/public-neutrality-report.txt -``` - -## Validate the public site - -Build the staged landing page and HTML documentation: +## Build and validate the public site ```powershell python scripts/build-public-site.py --output artifacts/public-site -``` - -Validate the staged output: - -```powershell .\scripts\validate-public-site.ps1 -SiteRoot artifacts/public-site ``` -The validator recursively checks: - -- one `

    ` per public page, -- descriptions and canonical URLs, -- canonical uniqueness, -- valid JSON-LD, -- local links and assets, -- documentation search-index targets, -- sitemap coverage, -- web-manifest icons, -- release filenames, +The site validator checks: + +- one H1 per page; +- meta descriptions and canonical URLs; +- canonical uniqueness; +- valid JSON-LD; +- local links and assets; +- documentation search-index targets; +- sitemap coverage; +- web-manifest icons; +- required release filenames; and - sitemap metadata in `robots.txt`. -The same builder and validator run inside GitHub Pages deployment. A broken page cannot deploy merely because another CI job has not finished. +Generated documentation pages identify GPL-3.0-or-later as the current community license and link to the separate commercial path without presenting it as an automatically granted alternative. -## Build portable release artifacts +## Build release artifacts ```powershell .\scripts\publish-release.ps1 -Version 0.4.0 @@ -137,7 +104,7 @@ Compatibility wrapper: .\publish-win-x64.ps1 -Version 0.4.0 ``` -Generated files: +Generated portable files: ```text artifacts/release/ @@ -146,17 +113,26 @@ artifacts/release/ └── ARSVIN-win-x64-portable.zip ``` -Staging files for the installer are generated under: +Installer staging is created under `artifacts/installer-input/`. + +The portable ZIP and installer staging include: ```text -artifacts/installer-input/ +README.md +LICENSE.txt +NOTICE.txt +COMMERCIAL-LICENSE.md +COPYRIGHT.md +TRADEMARK.md +THIRD_PARTY_NOTICES.md +docs/LICENSING.md ``` -The two direct `.exe` files are self-contained .NET 8 single-file applications. The ZIP includes both applications, essential documentation, license notices, and sample files. +`LICENSE.txt` must contain GNU GPL version 3. A historical Apache license file must not be included in a current GPL package. -## Generate the CycloneDX SBOM +## SBOM -After restoring the solution, run: +After restoring the solution: ```powershell .\scripts\generate-sbom.ps1 -Version 0.4.0 @@ -168,13 +144,11 @@ Output: artifacts/release/ARSVIN-SBOM.cdx.json ``` -The generator reads the locked, resolved NuGet graphs for Publisher and Subscriber, deduplicates direct and transitive application packages, records which application uses each package, and writes CycloneDX 1.5 JSON. Test-only packages are excluded. - -The SBOM includes a deterministic UUID URN `serialNumber`, source commit metadata, component version, and stable component ordering. It covers managed application dependencies; it does not claim to inventory Windows, Npcap, hosted-runner contents, or every build-service tool. +The CycloneDX 1.5 SBOM records locked managed runtime dependencies used by Publisher and Subscriber. It does not claim to inventory Windows, separately installed Npcap, hosted-runner contents, or every build-service component. -## Build the installer locally +## Installer -After running the publish script: +After publishing the applications: ```powershell $version = '0.4.0' @@ -189,24 +163,7 @@ $iscc = "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe" '.\installer\ARSVIN.iss' ``` -Output: - -```text -artifacts/release/ARSVIN-Suite-Setup-win-x64.exe -``` - -The automated workflow installs and verifies the exact package version declared in `INNO_SETUP_VERSION`. It records the compiler path and file metadata for evidence. - -The installer: - -- installs per-user under `%LOCALAPPDATA%\Programs\ARSVIN`, -- includes Publisher and Subscriber, -- creates Start Menu shortcuts, -- offers an optional Publisher desktop shortcut, -- includes an uninstaller, -- preserves Apache-2.0 and third-party notices, -- warns interactively when Npcap is not detected, -- supports unattended installation and removal without an Npcap message box. +The installer is per-user, contains Publisher and Subscriber, includes current legal and documentation files, creates Start Menu shortcuts, supports silent install and uninstall validation, and informs the user when Npcap is not detected. ## GitHub Actions release flow @@ -214,26 +171,24 @@ Workflow: `.github/workflows/release.yml` ### Pull-request validation -When release tooling, installer definitions, project files, dependency locks, or build configuration change, the workflow: +When release tooling or application inputs change, the workflow: -1. restores the locked dependency graph, -2. builds and tests with warnings treated as errors, -3. publishes both portable applications, -4. creates the portable suite ZIP, -5. installs and verifies pinned installer tooling, -6. compiles the installer, -7. generates and validates the CycloneDX SBOM, -8. checks expected artifact names and non-empty files, -9. silently installs the suite into a temporary directory, -10. verifies Publisher, Subscriber, documentation, version file, and uninstaller, -11. silently uninstalls the temporary installation, -12. generates checksums and uploads a private workflow artifact. +1. runs the licensing and wording gate through `build.ps1`; +2. restores, builds, and tests; +3. publishes both portable applications; +4. creates the portable suite ZIP; +5. installs pinned installer tooling; +6. compiles and smoke-tests the installer; +7. generates and validates the SBOM; +8. validates artifact names and non-empty files; +9. generates checksums; and +10. uploads a private workflow artifact. -A pull-request run never creates a public GitHub Release or public attestation. +A pull-request run does not create a public GitHub Release or public attestation. -### Stable tagged release +### Stable release -A public release is created only by pushing a semantic-version tag. The tagged commit must already be contained in `main`. +A release is created only by pushing a semantic-version tag whose commit is already contained in `main`: ```powershell git switch main @@ -242,71 +197,41 @@ git tag -a v0.4.0 -m "ARSVIN v0.4.0" git push origin v0.4.0 ``` -The workflow repeats the validated packaging path, downloads the validated artifact in a separate least-privilege release job, verifies that no GitHub Release already exists for the tag, creates signed provenance and SBOM attestations, and publishes the public files. - -Published GitHub Releases are immutable in automation. Any artifact correction requires a new patch version. - -### Prerelease tag +Published releases are immutable in automation. Corrections require a new semantic-version patch. -Semantic versions containing a suffix are published as prereleases and do not replace the latest stable release: - -```powershell -git switch main -git pull --ff-only origin main -git tag -a v0.5.0-rc.1 -m "ARSVIN v0.5.0-rc.1" -git push origin v0.5.0-rc.1 -``` - -### Manual artifact build - -Run **Build Windows Release** from the Actions tab and provide a version such as `0.5.0-dev.1`. - -Manual runs upload private workflow artifacts only. They never create or replace a public GitHub Release. +Prerelease suffixes such as `v0.5.0-rc.1` produce prereleases without replacing the latest stable release. Manual workflow dispatch produces private workflow artifacts only. ## Release assets | File | Description | |---|---| | `ARSVIN-Publisher-win-x64.exe` | Portable Publisher. | -| `ArSubsv-Subscriber-win-x64.exe` | Portable Subscriber/analysis companion. | +| `ArSubsv-Subscriber-win-x64.exe` | Portable Subscriber. | | `ARSVIN-Suite-Setup-win-x64.exe` | Installer for both applications. | | `ARSVIN-win-x64-portable.zip` | Portable suite package. | -| `ARSVIN-SBOM.cdx.json` | CycloneDX 1.5 managed application-dependency SBOM. | -| `SHA256SUMS.txt` | Integrity hashes for all release assets. | +| `ARSVIN-SBOM.cdx.json` | CycloneDX managed runtime-dependency SBOM. | +| `SHA256SUMS.txt` | Integrity hashes for release assets. | ## Verify a download -Verify the local hash: - ```powershell Get-FileHash .\ARSVIN-Suite-Setup-win-x64.exe -Algorithm SHA256 -``` - -Compare the result with `SHA256SUMS.txt` from the same release. - -Verify signed build provenance: - -```powershell gh attestation verify .\ARSVIN-Suite-Setup-win-x64.exe --repo masarray/arsvin ``` -Artifact attestations validate repository/workflow provenance; they are separate from Windows Authenticode signing. - -## Code signing status - -Release binaries are currently unsigned. Windows SmartScreen may display an unknown-publisher warning. The workflow intentionally does not contain placeholder signing steps or require paid signing secrets. +Checksums verify file integrity against the same release. Artifact attestations verify repository and workflow provenance. Neither is Windows Authenticode signing. -When a trusted certificate becomes available, sign the portable executables before compiling the installer, then sign the completed installer before checksum generation. +## Code-signing status -## Release checklist +Release binaries are currently unsigned. Windows SmartScreen may show an unknown-publisher warning. When a trusted certificate and operating process are available, sign the portable executables before installer compilation and sign the completed installer before checksum generation. -Before tagging a public release: +## Before tagging -- Confirm the intended release commit is already on `main`. -- Confirm `main` CI, release validation, and CodeQL are green. -- Update `VersionPrefix` and `CHANGELOG.md`. -- Confirm committed NuGet lock files match the reviewed dependency update. -- Review the generated application SBOM and checksums. -- Confirm no GitHub Release already exists for the intended tag. +- Confirm the intended commit is on `main`. +- Confirm CI, CodeQL, Pages validation, and release validation are green. +- Update `VersionPrefix`, `CHANGELOG.md`, and release notes. +- Review dependency locks, SBOM, checksums, legal notices, and package contents. +- Confirm no release already exists for the tag. - Test Publisher dry run and Subscriber PCAP import. -- Use a new patch version for any correction to an already published release. +- Use authorized isolated links for any live test. +- Use a new patch version for any correction to an existing release. \ No newline at end of file From 2e2b93b6d5fbcd330de42e07274eb0b6e823b585 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:15:04 +0700 Subject: [PATCH 33/69] Clarify third-party licensing boundary --- THIRD_PARTY_NOTICES.md | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index e051182..2993925 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -1,31 +1,41 @@ # Third-Party Notices -This file summarizes third-party components that ARSVIN depends on directly, includes in self-contained releases, or expects users to install for live packet capture and transmission. +ARSVIN project material covered by the current community license is distributed under `GPL-3.0-or-later`. The components below retain their own licenses and are not relicensed merely because they are used, restored, bundled, or documented by ARSVIN. + +This file summarizes third-party components that ARSVIN depends on directly, includes in self-contained releases, or expects users to install for live packet capture and transmission. Release SBOM data provides the resolved managed dependency graph for a specific build. ## SharpPcap - Package: `SharpPcap` -- Purpose: Packet capture and injection API used by ARSVIN Publisher and ArSubsv Subscriber +- Purpose: packet capture and injection API used by ARSVIN Publisher and ArSubsv Subscriber - License: MIT - Project: https://github.com/dotpcap/sharppcap - Package: https://www.nuget.org/packages/SharpPcap -SharpPcap is consumed as a NuGet package and is not authored by the ARSVIN maintainer. +SharpPcap is consumed as a NuGet package and is not authored by the ARSVIN maintainer. Its license and notices remain applicable. ## Npcap -- Purpose: Windows packet capture/transmission driver required for live Ethernet workflows +- Purpose: Windows packet capture and transmission driver for live Ethernet workflows - Project: https://npcap.com/ -Npcap is not bundled in this repository or silently installed by the ARSVIN installer. Users install it separately and are responsible for following its license and usage terms. +Npcap is not bundled in this repository or silently installed by the ARSVIN installer. Users install it separately and are responsible for its license and usage terms. ## .NET and WPF -ARSVIN is built with .NET and WPF. Self-contained release binaries include applicable .NET runtime components. See Microsoft documentation and license terms for those components. +ARSVIN is built with .NET and WPF. Self-contained release binaries include applicable .NET runtime components. The relevant Microsoft licenses and notices remain applicable to those components. ## Inno Setup -- Purpose: Build tooling and installer runtime used to create `ARSVIN-Suite-Setup-win-x64.exe` +- Purpose: build tooling and installer runtime used to create `ARSVIN-Suite-Setup-win-x64.exe` - Project: https://jrsoftware.org/isinfo.php -Inno Setup is not required to run the portable applications. Its license and third-party component notices apply to the generated installer as described by the Inno Setup project. +Inno Setup is not required to run the portable applications. Its license and third-party component notices apply to the generated installer as documented by that project. + +## Build and test dependencies + +The exact direct and transitive NuGet dependency graph is locked in committed `packages.lock.json` files. Tagged releases include a CycloneDX SBOM for resolved runtime dependencies. Test-only and hosted build-service components may be governed by additional licenses and are not necessarily part of the distributed application. + +## Commercial licensing boundary + +A separate ARSVIN commercial agreement can cover only rights controlled by the relevant copyright holder. It does not replace, sublicense beyond, or remove obligations imposed by third-party licenses. \ No newline at end of file From 2cf3693560c0c0448d21ea47b19fcc260e45cdf7 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:15:30 +0700 Subject: [PATCH 34/69] Refresh release notes and licensing boundary --- RELEASE_NOTES.md | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index f5fda29..2dbd046 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,12 +1,25 @@ # Release Notes -## v0.1.0 Preview +## Current development line -Initial public preview target: +ARSVIN is an IEC 61850 Sampled Values Publisher and Subscriber suite for Windows. -- IEC 61850 Sampled Values injection -- Up to three SV publishers -- SCL-based stream selection -- COMTRADE analog replay -- Lab PTP publisher and PTP monitor -- Portable Windows release workflow +Current public revisions are licensed under `GPL-3.0-or-later`. A separate negotiated commercial path is available for proprietary integration, OEM or white-label distribution, closed-source redistribution, private branches, and contractual engineering services. The commercial notice grants no additional rights by itself. + +Historical revisions through `9440f08b6909ef2dc93dd483cfdcb4e1e86077d0` remain available under Apache-2.0 on `archive/apache-2.0-final`. + +### Current capability summary + +- SCL-assisted Sampled Values stream configuration. +- Up to three Publisher slots with multi-ASDU packing. +- Manual, scenario, waveform-shaped, and COMTRADE sources. +- Generated PCAP, timing-health, and transmitter evidence. +- ArSubsv live Npcap and offline PCAP reception. +- Stream discovery, decoding, continuity diagnostics, waveform, phasor, RMS, and receiver evidence. +- Locked dependency graph, deterministic tests, coverage gates, SBOM, checksums, and artifact attestations. + +### Operational boundary + +ARSVIN can capture and transmit raw Ethernet frames. Use live features only under explicit authorization and an appropriate test boundary. The software is not calibrated deterministic real-time equipment, a formal IEC 61850 conformance platform, a functional-safety system, cybersecurity-certified equipment, or proof that another IED consumed or acted on a multicast stream. + +See [CHANGELOG.md](CHANGELOG.md), [docs/LICENSING.md](docs/LICENSING.md), and [docs/known-limitations.md](docs/known-limitations.md). \ No newline at end of file From 81480a733279948f529813a421b984556d607ac6 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:16:01 +0700 Subject: [PATCH 35/69] Refresh roadmap for Publisher Subscriber and licensing model --- ROADMAP.md | 123 +++++++++++++++++++++-------------------------------- 1 file changed, 48 insertions(+), 75 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index ceb1f57..3b1102e 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,87 +1,60 @@ # Roadmap -This roadmap keeps ARSVIN focused as a professional public IEC 61850 Sampled Values Publisher. +This roadmap keeps ARSVIN focused as an IEC 61850 Sampled Values Publisher, Subscriber, and evidence workbench. -## Done / in progress - -- Apache-2.0 public repository foundation. -- SCL-driven SV publishing workflow. -- COMTRADE replay workflow. -- P0 protocol-readiness pass: - - `nofASDU=1/2/4/8`, - - sequential per-ASDU sample counter, - - quality-bit foundation, - - generated PCAP export, - - TX Timing Health. -- P1 publisher evidence workflow: - - Markdown TX evidence report, - - preflight and stream summary, - - generated evidence scope wording. -- P2 full publisher scenario engine: - - protection fault, - - CT saturation stress approximation, - - undervoltage approximation, - - frequency steps, - - phase jump, - - load reversal. -- P3 public presentation pack: - - professional README, - - SEO landing page, - - social preview image, - - documentation index, - - public launch checklist. +Completed work belongs in [CHANGELOG.md](CHANGELOG.md). This document lists future priorities and claim boundaries. ## Near term -- Keep build/test green after every UI and protocol patch. -- Add more golden packet fixtures for SV, VLAN, quality, and nofASDU. -- Add screenshot assets captured from the real Windows app after build verification. -- Add a compatibility matrix based on lab validation with Wireshark and relay/subscriber tools. -- Improve SCL error messages and dataset mapping diagnostics. - -## Medium term - -- Add per-phase scenario model: - - single-phase fault, - - phase-to-phase fault, - - negative sequence, - - zero sequence, - - per-phase undervoltage / VT fuse fail. -- Add harmonic and DC-offset approximation for lab streams. -- Improve scenario timeline editing while keeping ARSVIN publisher-focused. -- Add CLI/headless dry-run and evidence generation mode. -- Split pure IEC 61850 engine code into a class library when the public API stabilizes. - -## Public credibility goals - -- Add real screenshots from the compiled Windows app. -- Add sample generated PCAP file and Wireshark field screenshots. -- Add release notes with known limitations and safety wording. -- Keep landing page and README aligned with actual capabilities. - -## Out of scope - -- Certified protection testing. -- Calibrated analog source replacement. -- Production substation network operation. -- General-purpose IEC 61850 analyzer scope creep. -- Live subscriber detection from SV publisher alone. -- Certified IEC 61850-9-3 PTP grandmaster behavior. - -## P2 full completed - -- Per-phase A-G and B-C fault presets. -- Negative-sequence and zero-sequence presets. -- Per-phase VT fuse fail preset. -- CT saturation stress with DC offset, harmonic, and clipping approximation. -- Harmonic injection and DC offset transient presets. +- Keep current-license, provenance, terminology, site, build, test, packaging, and release gates green. +- Expand malformed-frame, VLAN, quality, `nofASDU`, sample-counter, SCL, COMTRADE, and PCAP regression fixtures. +- Add more independently sourced or synthetic evidence packages with documented provenance. +- Improve SCL error messages, dataset mapping diagnostics, and configuration-versus-wire findings. +- Expand keyboard, scaling, accessibility, and long-session UI validation. +- Add clearer runtime evidence labels for automated tests, loopback, laboratory equipment, and approved commissioning environments. +- Audit release archives for required GPL, commercial, copyright, trademark, third-party, and historical-boundary documents. +## Publisher priorities +- Extend per-phase scenario modelling and reusable timeline editing. +- Add additional harmonic, DC-offset, clipping, and transient approximations for controlled laboratory streams. +- Improve timing-health evidence while preserving the explicit non-deterministic Windows scheduling boundary. +- Add headless dry-run, validation, PCAP generation, and report-generation workflows. +- Improve multi-stream resource and adapter diagnostics. -## ArSubsv Roadmap +## Subscriber priorities - Add PCAPNG import. - Add manual stream definitions when SCL is unavailable. -- Add cursor drag interaction in the oscilloscope plot. -- Add per-stream export of CSV waveform samples. -- Add richer IEC 61869-9 dataset presentation. +- Improve cursor and measurement interaction in waveform views. +- Add per-stream CSV waveform export. +- Expand IEC 61869-9-oriented dataset presentation only where requirements and evidence are documented. +- Improve traffic continuity, duplicate, reordering, rate-change, and payload-layout diagnostics. + +## Shared-engine priorities + +- Maintain protocol, SCL, profile, comparison, capture, and transport logic in `ARSVIN.Engine`. +- Expand deterministic tests for live-capture abstractions, scheduling boundaries, and transport failure recovery. +- Keep profile detection evidence-aware and prevent sparse observations from producing unqualified confirmation. +- Preserve unknown and unsupported traffic as observable evidence rather than silently normalizing it. +- Maintain locked dependencies, SBOM generation, and third-party notices. + +## Public credibility priorities + +- Keep README, landing page, generated documentation, release notes, and application wording aligned with implemented behavior. +- Maintain actual application screenshots and project-owned artwork. +- Publish known limitations and evidence scope beside download links. +- Add Authenticode signing when a trusted certificate and operational signing process are available. +- Maintain GPL-3.0-or-later as the only current community license and clearly separate historical grants from later releases. +- Review contributor rights, employment obligations, private artifacts, and trademarks before high-value commercial or OEM transactions. + +## Out of scope without a separately evidenced project decision + +- Formal IEC 61850 conformance certification. +- Calibrated analog-source or protection-test-set replacement. +- Deterministic real-time or functional-safety claims. +- Cybersecurity certification. +- Production substation network operation without explicit authority and an approved operational process. +- Proof that an IED consumed or acted on a multicast stream. +- Unqualified universal interoperability claims. +- Feature parity, branding, UI imitation, or report imitation based on unrelated proprietary products. \ No newline at end of file From 2e22eb2611004c511086897637e753e0a0a38c6c Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:16:28 +0700 Subject: [PATCH 36/69] Expand public terminology and licensing policy --- docs/public-terminology-policy.md | 41 ++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/docs/public-terminology-policy.md b/docs/public-terminology-policy.md index 1488b30..b97a242 100644 --- a/docs/public-terminology-policy.md +++ b/docs/public-terminology-policy.md @@ -1,18 +1,41 @@ # Public Terminology Policy -ARSVIN public documentation describes engineering outcomes, protocol behavior, standards references, and evidence requirements in neutral terms. +ARSVIN public documentation describes engineering outcomes, protocol behavior, standards references, evidence requirements, licensing, and operational boundaries in neutral and verifiable terms. ## Public content rules -- Do not use proprietary product comparisons as feature requirements. -- Do not imply compatibility, endorsement, certification, or equivalence with third-party products. -- Describe desired outcomes such as SCL-versus-wire comparison, orphan detection, stream-health analysis, triggered evidence capture, and repeatable reporting. -- Cite applicable standards publications and implementation guidelines without reproducing protected standard text. -- Keep manufacturer-specific observations inside authorized evidence records and publish only anonymized or synthetic regression fixtures. -- Record source provenance separately from product-facing language. +- Do not use unrelated product comparisons, branding, UI, reports, or marketing language as feature requirements. +- Do not imply compatibility, endorsement, certification, approval, or equivalence with another product or organization. +- Describe desired outcomes directly: SCL-versus-wire comparison, continuity diagnostics, stream-health analysis, transmitter evidence, receiver evidence, and repeatable reporting. +- Cite applicable standards publications and public implementation guidance without reproducing protected standard text. +- Keep manufacturer-specific observations inside authorized evidence records and publish only synthetic, contributor-owned, or documented authorized fixtures. +- Record requirement and fixture provenance separately from product-facing language. +- Distinguish configured expectations, observed traffic, software interpretation, and external-device behavior. +- Identify evidence sources such as deterministic tests, simulator, loopback, isolated laboratory equipment, or approved commissioning work. + +## Claims requiring qualification + +Do not use unqualified claims such as certified, conformant, compliant, calibrated, deterministic, real-time accurate, safe, secure, trusted, universal, production-ready, field-proven, or guaranteed. + +Use scoped evidence wording such as implemented, covered by the stated test, observed on the selected adapter, laboratory-exercised, provisional, partial, unsupported, unknown, or not yet verified. + +ARSVIN does not establish functional safety, cybersecurity approval, switching authority, equipment isolation, calibrated measurement, deterministic execution, or proof that another IED consumed multicast traffic. + +## Licensing terminology + +- Current community source and current releases are `GPL-3.0-or-later` only. +- Historical Apache-2.0 references must identify the exact historical boundary and must not imply a current Apache-or-GPL choice. +- The commercial licensing notice is an invitation to negotiate and does not itself grant additional rights. +- Commercial terms can cover only rights controlled by the relevant copyright holder. +- Third-party components retain their own licenses and notices. ## Automated validation -CI and Pages deployment run `scripts/validate-public-neutrality.py` before building public documentation. The validator checks active public content and blocks prohibited comparison terminology. +CI, Pages, build, and release paths run: + +```text +scripts/verify-current-license.py +scripts/validate-public-neutrality.py +``` -This validation protects the current repository tree. Historical Git commits remain part of normal repository history and should not be treated as current product documentation. +These controls protect the current tracked tree and generated public content. Historical commits remain repository history and are not current product documentation. \ No newline at end of file From ee5b9b4fc57e3c1c51a17a824daa07aaf66aee2e Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:17:01 +0700 Subject: [PATCH 37/69] Separate cybersecurity and operational reporting boundaries --- SECURITY.md | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 7ea8c9f..4e040ff 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,29 +1,38 @@ # Security Policy -ARSVIN can transmit raw Ethernet frames. Security and safety reports are taken seriously because misuse on a live process-bus or substation network can create operational risk. +ARSVIN can capture and transmit raw Ethernet frames. Cybersecurity vulnerabilities and operational-risk defects are reviewed separately but both require careful handling because live use may affect a test network or connected equipment. ## Supported versions -Only the current `main` branch and the latest public release are supported for security review. +Only the current `main` branch and latest public release are supported for security review. Historical archive branches preserve earlier licensing and source history but are not maintained security release lines. -## Reporting a vulnerability +## Report a cybersecurity vulnerability -Please report security issues privately by opening a GitHub Security Advisory on the repository. If that is not possible, contact the maintainer through GitHub. +Use GitHub private vulnerability reporting or a private Security Advisory. When that is unavailable, contact the maintainer through the `masarray` GitHub profile without posting exploit details publicly. -Please include: +Include: -- A clear description of the issue -- A minimal reproduction case, if safe to share -- Affected version or commit -- Whether live Ethernet transmission is involved -- Any relevant packet details, with confidential information removed +- a clear description and affected version or commit; +- the security boundary or trust assumption that fails; +- the smallest reproducible case that can be shared lawfully; +- whether packet capture, transmission, file parsing, installer, update, or privilege behavior is involved; and +- sanitized evidence with credentials, customer information, station identifiers, restricted addressing, and proprietary material removed. -## Responsible disclosure expectations +## Report an operational-risk defect -- Do not test against networks or devices without authorization. -- Do not publish exploit details before the maintainer has had a reasonable opportunity to respond. -- Do not include real substation SCL files, relay credentials, internal IP plans, or production packet captures in public issues. +Issues such as unintended transmission, incorrect adapter selection, missing live-mode confirmation, misleading evidence, unexpected stream persistence, timing-health misreporting, or failure to stop output may be reported as operational defects. Use a public issue only when all details are sanitized; otherwise contact the maintainer privately. -## Safety boundary +Software checks do not establish network authorization, equipment isolation, switching authority, functional safety, or process safety. -ARSVIN is intended for isolated lab networks, point-to-point test links, and engineering education. It is not designed for production substations, closed-loop protection validation, or calibrated protection testing. +## Responsible disclosure + +- Do not test networks, devices, drivers, or installers without authorization. +- Do not publish exploit or hazardous reproduction details before reasonable coordinated review. +- Do not upload real station SCL, credentials, production captures, internal network plans, customer identity, or proprietary third-party material to public issues. +- Use synthetic or contributor-owned fixtures whenever practical. + +## Product boundary + +ARSVIN is intended for authorized laboratory, development, troubleshooting, commissioning-support, and education workflows. It is not calibrated deterministic real-time equipment, a formal conformance platform, a functional-safety system, a cybersecurity-certified product, or proof that an IED consumed or acted on a multicast stream. + +The software is provided under GPL-3.0-or-later without warranty, except where a separate written agreement expressly states otherwise. \ No newline at end of file From 70b739db20d0ec849a829080e433450a864f2dda Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:17:31 +0700 Subject: [PATCH 38/69] Clarify community commercial and data support boundaries --- SUPPORT.md | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/SUPPORT.md b/SUPPORT.md index 3ee5eb5..9c535b8 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -1,17 +1,34 @@ # Support -Use GitHub Issues for reproducible bugs, feature requests, documentation improvements, and lab workflow questions. +Use GitHub Issues for reproducible community-edition bugs, focused feature requests, documentation improvements, and authorized laboratory workflow questions. -Please include: +## Include -- ARSVIN version or commit -- Windows version -- .NET SDK version if building from source -- Npcap version -- Whether the issue is dry run, live publish, SCL setup, COMTRADE replay, PTP, or UI related -- SCL/COMTRADE sample if it can be shared safely -- Screenshots or Wireshark notes when relevant +- ARSVIN version or commit; +- application: Publisher or ArSubsv Subscriber; +- Windows and Npcap versions; +- .NET SDK version when building from source; +- workflow type: offline configuration, dry run, live capture, live transmission, SCL, COMTRADE, PCAP, timing, report, installer, or UI; +- exact reproduction steps and expected versus observed behavior; +- evidence environment: automated test, simulator, loopback, isolated laboratory equipment, or approved commissioning environment; and +- the smallest sanitized diagnostic, screenshot, or independent packet-analysis note needed to explain the issue. -Do not share confidential station files, real relay credentials, internal network details, or production packet captures in public issues. +## Data boundary -For security-sensitive issues, use the process in [SECURITY.md](SECURITY.md). +Use synthetic or contributor-owned examples whenever practical. Do not post: + +- confidential customer, employer, station, or project files; +- credentials, private keys, restricted addresses, or internal network plans; +- production packet captures or private SCL/COMTRADE files without explicit redistribution authority; +- proprietary manuals, support responses, screenshots, reports, binaries, or copied UI assets; or +- exploit details that should be handled through private vulnerability reporting. + +Sanitization must preserve the technical condition being reported without exposing protected information. + +## Scope + +Community support is best effort and does not imply warranty, response-time commitment, formal conformance assessment, calibrated testing, functional-safety approval, cybersecurity certification, switching authority, or confirmation that an IED consumed multicast traffic. + +For security-sensitive issues, follow [SECURITY.md](SECURITY.md). + +For proprietary integration, OEM or white-label distribution, private branches, contractual response times, training, warranty, or engineering services, review [COMMERCIAL-LICENSE.md](COMMERCIAL-LICENSE.md) and contact the project owner privately through the `masarray` GitHub profile. The notice is an invitation to discuss terms and grants no additional rights by itself. \ No newline at end of file From 6a90ebbda5d4a0aaaf9da84001059321c596d7a7 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:18:13 +0700 Subject: [PATCH 39/69] Clarify operational and evidence boundaries --- docs/safety-boundaries.md | 46 +++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/docs/safety-boundaries.md b/docs/safety-boundaries.md index 8057547..992ae8a 100644 --- a/docs/safety-boundaries.md +++ b/docs/safety-boundaries.md @@ -1,13 +1,41 @@ -# Safety Boundaries +# Operational and Evidence Boundaries -ARSVIN is an engineering, lab, and R&D tool focused on IEC 61850 Sampled Values publishing and process-bus traffic testing. +ARSVIN is engineering software for IEC 61850 Sampled Values generation, reception, decoding, visualization, diagnostics, and evidence on authorized laboratory or test networks. -It is not: +## What the software can establish -- a certified protection test set -- a calibrated current or voltage source -- a calibrated PTP grandmaster -- a substitute for formal FAT / SAT test authority -- a deterministic real-time protection performance test platform +Depending on the workflow and evidence source, ARSVIN can record: -Use ARSVIN only on networks where raw Ethernet traffic generation is authorized and understood. +- configured SCL expectations; +- frames generated by the Publisher; +- frames observed by the selected computer and adapter; +- decoded payload values, counters, timing observations, waveform, phasor, and RMS calculations; +- continuity, configuration, and payload-layout findings; and +- reproducible PCAP and Markdown evidence. + +## What the software does not establish + +ARSVIN does not by itself establish: + +- that another IED received, accepted, trusted, or acted on a multicast stream; +- calibrated current, voltage, phase, time, or protection-performance accuracy; +- deterministic real-time execution; +- formal IEC 61850 conformance or certification; +- functional-safety approval or cybersecurity certification; +- equipment isolation, switching authority, site authorization, or process safety; +- a replacement for an approved FAT, SAT, commissioning, or maintenance procedure; or +- suitability for unattended production process-bus monitoring. + +## Live Ethernet use + +Raw Ethernet capture and transmission are active network operations. Use them only when: + +- the network and connected equipment are explicitly authorized for the test; +- the adapter and test topology have been independently verified; +- an approved test plan and responsible person are in place; +- expected process consequences and recovery steps are understood; and +- evidence is stored without exposing confidential or restricted information. + +A dry run, synthetic sample, PCAP import, or isolated point-to-point link should be used before any broader live-network exercise. + +Software preflight checks are operational guardrails. They cannot prove that the external test environment is safe, isolated, authorized, or free from process consequences. \ No newline at end of file From e0fd0f1605d171cf907f6aa81742f5877713c065 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:18:40 +0700 Subject: [PATCH 40/69] Replace broad safety wording with live-operation guardrails --- docs/live-mode-safety.md | 42 ++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/docs/live-mode-safety.md b/docs/live-mode-safety.md index 6c60149..52211bf 100644 --- a/docs/live-mode-safety.md +++ b/docs/live-mode-safety.md @@ -1,32 +1,36 @@ -# Live Mode Safety +# Live Network Guardrails -Live mode transmits raw Ethernet Sampled Values traffic on the selected network adapter. +Live mode transmits raw Ethernet Sampled Values traffic through the selected network adapter. This is an active network operation. ## Use live mode only when -- you are on an isolated lab network, process-bus test bench, or direct point-to-point setup -- the selected adapter is the intended adapter -- the target relay / subscriber is expected to receive test traffic -- the APPID, VLAN, destination MAC, and `smpSynch` compatibility behavior have been reviewed +- the network, connected equipment, and test are explicitly authorized; +- the topology is an isolated laboratory network, controlled process-bus test bench, or direct point-to-point link; +- the selected adapter has been independently verified; +- the expected receiver is prepared for the test traffic; +- APPID, VLAN, destination MAC, sample rate, payload layout, and `smpSynch` behavior have been reviewed; and +- a responsible test plan, observation method, stop condition, and recovery step are in place. -## Before starting live publish +## Before live transmission -Confirm the following: +Verify: -- correct adapter selected -- Npcap installed and working -- application running with sufficient privileges -- correct destination multicast MAC -- correct APPID and VLAN -- expected sample rate -- chosen `smpSynch` mode is understood: compatibility modes help relay readability, but do not prove real PTP accuracy +- dry-run or offline generation completed as expected; +- Npcap is installed and working; +- required local permissions are available; +- destination multicast MAC, APPID, and VLAN are correct; +- dataset, sample rate, `nofASDU`, counter wrap, and payload mapping are understood; +- the chosen synchronization indication matches the intended test; and +- evidence recording and independent packet observation are ready. -## Important +Compatibility-oriented `smpSynch` modes may support laboratory behavior checks. They do not prove PTP accuracy, time traceability, merging-unit performance, or receiver acceptance. -ARSVIN is for lab publishing, relay readability checks, and traffic experiments. +## Evidence limit -It is not intended to be used as a certified protection commissioning authority or calibrated acceptance-test source. +Publisher evidence records what ARSVIN generated. A capture from the selected computer or an independent analyzer records what that observation point received. Neither proves that a protection IED consumed or acted on the stream. ## Preflight behavior -Warnings are advisory and do not block KM Looptest / point-to-point lab publishing. Fatal errors still block live publish when ARSVIN cannot build or send a valid stream. +Warnings and readiness results are software guardrails. Fatal errors block transmission when ARSVIN cannot build or send the selected stream. Advisory results do not establish network authorization, isolation, functional safety, process safety, or protection-system suitability. + +ARSVIN is not a certified protection commissioning authority, calibrated acceptance-test source, deterministic real-time platform, or formal IEC 61850 conformance tool. \ No newline at end of file From 59e8723778775618c50bf34b87c1a1f9cb3a6fbd Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:19:57 +0700 Subject: [PATCH 41/69] Record the ARSVIN license transition --- docs/LICENSE_TRANSITION_RECORD_2026-07-14.md | 49 ++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 docs/LICENSE_TRANSITION_RECORD_2026-07-14.md diff --git a/docs/LICENSE_TRANSITION_RECORD_2026-07-14.md b/docs/LICENSE_TRANSITION_RECORD_2026-07-14.md new file mode 100644 index 0000000..21e873c --- /dev/null +++ b/docs/LICENSE_TRANSITION_RECORD_2026-07-14.md @@ -0,0 +1,49 @@ +# License Transition Record — 2026-07-14 + +## Historical boundary + +The last revision released as the active Apache-2.0 project line is: + +```text +9440f08b6909ef2dc93dd483cfdcb4e1e86077d0 +``` + +It is preserved on: + +```text +archive/apache-2.0-final +``` + +Historical grants for that revision and earlier revisions remain effective under their original terms. + +## Current line + +Revisions after that boundary on `main` are released as the ARSVIN community edition under: + +```text +GPL-3.0-or-later +``` + +Current release packages must contain the GNU GPL version 3 text and must not include a historical Apache license file in a way that suggests a current license choice. + +## Commercial path + +A separate commercial agreement may provide additional rights for material controlled by the relevant copyright holder. `COMMERCIAL-LICENSE.md` is only an invitation to negotiate and grants no additional rights by itself. + +Third-party dependencies, contributor-owned material, standards, and historical grants retain their applicable rights and notices. + +## Transition controls + +The transition adds: + +- current-license verification; +- GPL package metadata; +- historical branch and documentation; +- commercial, copyright, trademark, CLA, DCO, and provenance files; +- updated README, website, generated documentation, installer, and release packaging; +- public wording and operational claim boundaries; and +- CI and Pages enforcement. + +## Limitations + +This record documents repository actions and public licensing intent. It does not establish employer ownership, resolve private contractual obligations, or replace legal review for a significant commercial transaction. \ No newline at end of file From 9138cecea86e961c5c684876c08b998f17289d86 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:20:24 +0700 Subject: [PATCH 42/69] Add concise current licensing summary --- docs/CURRENT_LICENSE_SUMMARY.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 docs/CURRENT_LICENSE_SUMMARY.md diff --git a/docs/CURRENT_LICENSE_SUMMARY.md b/docs/CURRENT_LICENSE_SUMMARY.md new file mode 100644 index 0000000..e5a18d6 --- /dev/null +++ b/docs/CURRENT_LICENSE_SUMMARY.md @@ -0,0 +1,10 @@ +# Current License Summary + +```text +Current community source and releases: GPL-3.0-or-later +Historical revisions through 9440f08b6909ef2dc93dd483cfdcb4e1e86077d0: Apache-2.0 +Historical branch: archive/apache-2.0-final +Proprietary, OEM, or white-label rights: separate negotiated commercial agreement +``` + +The commercial notice is not itself a license and grants no additional rights. Third-party components retain their applicable licenses. See [LICENSING.md](LICENSING.md) for the complete boundary. \ No newline at end of file From f43dbb3b1fb15baaba95f03921ec4bdd441f7f62 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:20:35 +0700 Subject: [PATCH 43/69] Add documentation entry point --- docs/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..56fed2d --- /dev/null +++ b/docs/README.md @@ -0,0 +1,14 @@ +# ARSVIN Documentation Entry Point + +The canonical documentation index is [index.md](index.md). + +Start with: + +- [Quick Start](quick-start.md) +- [Operational and Evidence Boundaries](safety-boundaries.md) +- [Known Limitations](known-limitations.md) +- [Licensing](LICENSING.md) +- [External IP and Provenance Review](EXTERNAL_IP_AND_PROVENANCE_REVIEW_2026-07-14.md) +- [Public Wording and Claim Review](WORDING_AND_CLAIM_REVIEW_2026-07-14.md) + +Current community source and current releases are `GPL-3.0-or-later`. Commercial rights require a separate negotiated agreement. \ No newline at end of file From 491de8b168308a5d5c357245a2df82fca128fa0d Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:20:53 +0700 Subject: [PATCH 44/69] Add commercial licensing FAQ --- docs/COMMERCIAL_LICENSING_FAQ.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 docs/COMMERCIAL_LICENSING_FAQ.md diff --git a/docs/COMMERCIAL_LICENSING_FAQ.md b/docs/COMMERCIAL_LICENSING_FAQ.md new file mode 100644 index 0000000..d91a5b1 --- /dev/null +++ b/docs/COMMERCIAL_LICENSING_FAQ.md @@ -0,0 +1,25 @@ +# Commercial Licensing FAQ + +## Is the repository dual-licensed GPL or commercial by default? + +No. The public community edition is licensed under `GPL-3.0-or-later`. Commercial rights require a separate negotiated and executed agreement. + +## Does `COMMERCIAL-LICENSE.md` grant proprietary rights? + +No. It is an invitation to discuss terms and grants no additional rights by itself. + +## Why offer a commercial path? + +Organizations may need proprietary integration, OEM or white-label redistribution, private branches, contractual support, warranty, training, or engineering services that are not provided by the public GPL grant. + +## What can a commercial agreement cover? + +Only rights controlled by the relevant copyright holder. Third-party dependencies, contributor-owned material, standards, and historical grants remain subject to their applicable terms. + +## Do historical Apache rights disappear? + +No. Revisions up to and including `9440f08b6909ef2dc93dd483cfdcb4e1e86077d0` retain their historical Apache-2.0 grants on `archive/apache-2.0-final`. Later community revisions and current release binaries are not offered as an Apache-or-GPL choice. + +## Does a commercial agreement certify the product? + +Not automatically. Licensing, support, warranty, validation, conformance assessment, calibration, functional safety, cybersecurity approval, and engineering acceptance are separate contractual and technical subjects. \ No newline at end of file From e412400e0b51058d9092bdd79cdd522d54704aa5 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:21:04 +0700 Subject: [PATCH 45/69] Document required package legal files --- docs/PACKAGE_LEGAL_CONTENT.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 docs/PACKAGE_LEGAL_CONTENT.md diff --git a/docs/PACKAGE_LEGAL_CONTENT.md b/docs/PACKAGE_LEGAL_CONTENT.md new file mode 100644 index 0000000..3ff5eed --- /dev/null +++ b/docs/PACKAGE_LEGAL_CONTENT.md @@ -0,0 +1,19 @@ +# Current Package Legal Content + +Every current ARSVIN installer and portable suite package must include: + +```text +LICENSE.txt +NOTICE.txt +COMMERCIAL-LICENSE.md +COPYRIGHT.md +TRADEMARK.md +THIRD_PARTY_NOTICES.md +docs/LICENSING.md +``` + +`LICENSE.txt` must contain GNU GPL version 3. `COMMERCIAL-LICENSE.md` must state that it grants no additional rights by itself. + +Current packages must not contain `LICENSE-APACHE-2.0` or present Apache-2.0 as a current alternative license. Historical revisions and their license remain available separately on `archive/apache-2.0-final`. + +Third-party licenses and notices remain applicable and must not be removed or replaced by the ARSVIN project license. \ No newline at end of file From 0bb1b1d78703e048816982f82e0b501800510dbb Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:21:19 +0700 Subject: [PATCH 46/69] Add completed licensing transition checklist --- docs/TRANSITION_CHECKLIST.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 docs/TRANSITION_CHECKLIST.md diff --git a/docs/TRANSITION_CHECKLIST.md b/docs/TRANSITION_CHECKLIST.md new file mode 100644 index 0000000..8f103aa --- /dev/null +++ b/docs/TRANSITION_CHECKLIST.md @@ -0,0 +1,14 @@ +# Licensing Transition Checklist + +- [x] Preserve the last Apache-2.0 revision on `archive/apache-2.0-final`. +- [x] Replace the active root license with GNU GPL version 3. +- [x] Declare `GPL-3.0-or-later` in project metadata. +- [x] Add a separate commercial licensing notice. +- [x] Add copyright and trademark policies. +- [x] Add CLA and DCO contribution records. +- [x] Update README, website, structured data, manifest, and generated documentation. +- [x] Update installer and portable package legal content. +- [x] Add current-license, provenance, and wording verification. +- [x] Update CI, Pages, build, and release validation paths. +- [x] Record operational, conformance, evidence, and external-material boundaries. +- [ ] Complete any organization-specific employment, invention-assignment, confidentiality, and trademark review required for a significant commercial agreement. \ No newline at end of file From 4fd76a95de354daeb1ac3c56c25ed648c7a4354e Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:21:37 +0700 Subject: [PATCH 47/69] Add legal and provenance navigation --- docs/LEGAL_AND_PROVENANCE_INDEX.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 docs/LEGAL_AND_PROVENANCE_INDEX.md diff --git a/docs/LEGAL_AND_PROVENANCE_INDEX.md b/docs/LEGAL_AND_PROVENANCE_INDEX.md new file mode 100644 index 0000000..7b4a8e5 --- /dev/null +++ b/docs/LEGAL_AND_PROVENANCE_INDEX.md @@ -0,0 +1,20 @@ +# Legal and Provenance Index + +- [Current licensing model](LICENSING.md) +- [Current license summary](CURRENT_LICENSE_SUMMARY.md) +- [License transition record](LICENSE_TRANSITION_RECORD_2026-07-14.md) +- [Commercial licensing FAQ](COMMERCIAL_LICENSING_FAQ.md) +- [Current package legal content](PACKAGE_LEGAL_CONTENT.md) +- [External IP and provenance review](EXTERNAL_IP_AND_PROVENANCE_REVIEW_2026-07-14.md) +- [Public wording and claim review](WORDING_AND_CLAIM_REVIEW_2026-07-14.md) +- [Transition checklist](TRANSITION_CHECKLIST.md) + +Root policies: + +- [GPL license](../LICENSE) +- [Commercial licensing notice](../COMMERCIAL-LICENSE.md) +- [Copyright](../COPYRIGHT.md) +- [Trademark and branding](../TRADEMARK.md) +- [Contributor License Agreement](../CONTRIBUTOR-LICENSE-AGREEMENT.md) +- [Developer Certificate of Origin](../DCO.txt) +- [Third-party notices](../THIRD_PARTY_NOTICES.md) \ No newline at end of file From 46e1dffaaac744b0f16a58d6bc6f63a36c43a56c Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:21:50 +0700 Subject: [PATCH 48/69] Describe community and commercial model --- docs/COMMUNITY_AND_COMMERCIAL_MODEL.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 docs/COMMUNITY_AND_COMMERCIAL_MODEL.md diff --git a/docs/COMMUNITY_AND_COMMERCIAL_MODEL.md b/docs/COMMUNITY_AND_COMMERCIAL_MODEL.md new file mode 100644 index 0000000..443ebb4 --- /dev/null +++ b/docs/COMMUNITY_AND_COMMERCIAL_MODEL.md @@ -0,0 +1,24 @@ +# Community and Commercial Model + +## Community edition + +The public ARSVIN community edition is available under `GPL-3.0-or-later`. Users receive the rights and obligations stated in the GNU GPL and applicable third-party licenses. + +## Commercial agreement + +A separately negotiated agreement may provide additional rights or services for proprietary integration, OEM or white-label distribution, closed-source redistribution, private branches, warranty, maintenance, priority response, training, or engineering work. + +No commercial rights arise merely from the presence of `COMMERCIAL-LICENSE.md` in the repository. + +## Shared boundaries + +Both channels remain subject to: + +- rights actually controlled by the relevant copyright holder; +- third-party licenses and notices; +- applicable standards-access terms; +- trademark and branding restrictions; +- operational authorization and safety processes; and +- separately agreed warranties, validation scope, and acceptance criteria. + +The licensing channel does not change technical evidence into a certification, calibrated result, functional-safety approval, cybersecurity approval, or proof of external-device behavior. \ No newline at end of file From c0b54cc6c7045e8b538e34b22d925a9d15eb92d9 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:22:05 +0700 Subject: [PATCH 49/69] Add concise legal notice for documentation readers --- docs/README_LEGAL_NOTICE.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/README_LEGAL_NOTICE.md diff --git a/docs/README_LEGAL_NOTICE.md b/docs/README_LEGAL_NOTICE.md new file mode 100644 index 0000000..b30b8d4 --- /dev/null +++ b/docs/README_LEGAL_NOTICE.md @@ -0,0 +1,5 @@ +# Documentation Legal Notice + +Current ARSVIN community source and releases are `GPL-3.0-or-later`. Additional proprietary or OEM rights require a separately negotiated agreement. Third-party components retain their applicable licenses. + +Engineering documentation and software output are not formal conformance, calibration, functional-safety, cybersecurity, or external-device acceptance certificates. \ No newline at end of file From 4e90a04193634df35e8accba9b5e591a5d6118c6 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:22:20 +0700 Subject: [PATCH 50/69] Document current-release license clarity rule --- docs/DO_NOT_DUAL_LICENSE_CURRENT_RELEASES.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 docs/DO_NOT_DUAL_LICENSE_CURRENT_RELEASES.md diff --git a/docs/DO_NOT_DUAL_LICENSE_CURRENT_RELEASES.md b/docs/DO_NOT_DUAL_LICENSE_CURRENT_RELEASES.md new file mode 100644 index 0000000..b53f55c --- /dev/null +++ b/docs/DO_NOT_DUAL_LICENSE_CURRENT_RELEASES.md @@ -0,0 +1,13 @@ +# Current Release License Clarity Rule + +Current ARSVIN community releases must not be described or packaged as Apache-2.0 OR GPL-3.0-or-later. + +The correct model is: + +```text +Current community source and releases: GPL-3.0-or-later +Historical revisions: Apache-2.0 through the recorded boundary commit +Commercial rights: separate negotiated agreement +``` + +Historical license preservation is not a current dual-license offer. A commercial licensing notice is not an automatically granted alternative license. \ No newline at end of file From 05472fb16a45f273a4bf7b4494a770253d1936b3 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:22:34 +0700 Subject: [PATCH 51/69] Add final legal model summary --- docs/FINAL_LEGAL_MODEL.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 docs/FINAL_LEGAL_MODEL.md diff --git a/docs/FINAL_LEGAL_MODEL.md b/docs/FINAL_LEGAL_MODEL.md new file mode 100644 index 0000000..10e78a4 --- /dev/null +++ b/docs/FINAL_LEGAL_MODEL.md @@ -0,0 +1,15 @@ +# Final Legal Model + +```text +ARSVIN current community edition +GPL-3.0-or-later only + +ARSVIN historical revisions +Apache-2.0 through 9440f08b6909ef2dc93dd483cfdcb4e1e86077d0 +archive/apache-2.0-final + +Proprietary, OEM, white-label, or closed-source rights +Separate negotiated and executed commercial agreement +``` + +This model does not remove historical grants, third-party obligations, or the need to confirm ownership and contractual authority for the exact commercial deliverable. \ No newline at end of file From a443d3ceb9b73e463c4990ff5b7f88df29baa76d Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:22:49 +0700 Subject: [PATCH 52/69] Clarify commercial rights notice --- docs/COMMERCIAL_RIGHTS_NOTICE.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/COMMERCIAL_RIGHTS_NOTICE.md diff --git a/docs/COMMERCIAL_RIGHTS_NOTICE.md b/docs/COMMERCIAL_RIGHTS_NOTICE.md new file mode 100644 index 0000000..baf2091 --- /dev/null +++ b/docs/COMMERCIAL_RIGHTS_NOTICE.md @@ -0,0 +1,5 @@ +# Commercial Rights Notice + +No proprietary, OEM, white-label, warranty, private-branch, or closed-source redistribution rights are granted by this repository notice alone. + +Such rights require a separate written agreement signed or otherwise executed by the relevant parties. The agreement can cover only rights controlled by the granting party and cannot remove third-party license obligations. \ No newline at end of file From 06ef8e9f62867bd4d8c9128a1dea55ccb604c5c9 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:24:57 +0700 Subject: [PATCH 53/69] Remove redundant legal summary document --- docs/README_LEGAL_NOTICE.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 docs/README_LEGAL_NOTICE.md diff --git a/docs/README_LEGAL_NOTICE.md b/docs/README_LEGAL_NOTICE.md deleted file mode 100644 index b30b8d4..0000000 --- a/docs/README_LEGAL_NOTICE.md +++ /dev/null @@ -1,5 +0,0 @@ -# Documentation Legal Notice - -Current ARSVIN community source and releases are `GPL-3.0-or-later`. Additional proprietary or OEM rights require a separately negotiated agreement. Third-party components retain their applicable licenses. - -Engineering documentation and software output are not formal conformance, calibration, functional-safety, cybersecurity, or external-device acceptance certificates. \ No newline at end of file From c3faaa20f813fbf1e9b07c8e88a43f46f682cbdc Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:25:07 +0700 Subject: [PATCH 54/69] Remove redundant current-license rule document --- docs/DO_NOT_DUAL_LICENSE_CURRENT_RELEASES.md | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 docs/DO_NOT_DUAL_LICENSE_CURRENT_RELEASES.md diff --git a/docs/DO_NOT_DUAL_LICENSE_CURRENT_RELEASES.md b/docs/DO_NOT_DUAL_LICENSE_CURRENT_RELEASES.md deleted file mode 100644 index b53f55c..0000000 --- a/docs/DO_NOT_DUAL_LICENSE_CURRENT_RELEASES.md +++ /dev/null @@ -1,13 +0,0 @@ -# Current Release License Clarity Rule - -Current ARSVIN community releases must not be described or packaged as Apache-2.0 OR GPL-3.0-or-later. - -The correct model is: - -```text -Current community source and releases: GPL-3.0-or-later -Historical revisions: Apache-2.0 through the recorded boundary commit -Commercial rights: separate negotiated agreement -``` - -Historical license preservation is not a current dual-license offer. A commercial licensing notice is not an automatically granted alternative license. \ No newline at end of file From d5360a2176e80973328fb8f6b94deabc18aeddf7 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:25:21 +0700 Subject: [PATCH 55/69] Remove redundant final legal model summary --- docs/FINAL_LEGAL_MODEL.md | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 docs/FINAL_LEGAL_MODEL.md diff --git a/docs/FINAL_LEGAL_MODEL.md b/docs/FINAL_LEGAL_MODEL.md deleted file mode 100644 index 10e78a4..0000000 --- a/docs/FINAL_LEGAL_MODEL.md +++ /dev/null @@ -1,15 +0,0 @@ -# Final Legal Model - -```text -ARSVIN current community edition -GPL-3.0-or-later only - -ARSVIN historical revisions -Apache-2.0 through 9440f08b6909ef2dc93dd483cfdcb4e1e86077d0 -archive/apache-2.0-final - -Proprietary, OEM, white-label, or closed-source rights -Separate negotiated and executed commercial agreement -``` - -This model does not remove historical grants, third-party obligations, or the need to confirm ownership and contractual authority for the exact commercial deliverable. \ No newline at end of file From 6088e7f63138a1f5d88aa47f338ab28ee8ecdc5b Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:25:30 +0700 Subject: [PATCH 56/69] Remove redundant commercial rights summary --- docs/COMMERCIAL_RIGHTS_NOTICE.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 docs/COMMERCIAL_RIGHTS_NOTICE.md diff --git a/docs/COMMERCIAL_RIGHTS_NOTICE.md b/docs/COMMERCIAL_RIGHTS_NOTICE.md deleted file mode 100644 index baf2091..0000000 --- a/docs/COMMERCIAL_RIGHTS_NOTICE.md +++ /dev/null @@ -1,5 +0,0 @@ -# Commercial Rights Notice - -No proprietary, OEM, white-label, warranty, private-branch, or closed-source redistribution rights are granted by this repository notice alone. - -Such rights require a separate written agreement signed or otherwise executed by the relevant parties. The agreement can cover only rights controlled by the granting party and cannot remove third-party license obligations. \ No newline at end of file From 50287abe6f845a008c62c6aea73d558e6bfcf33c Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:25:43 +0700 Subject: [PATCH 57/69] Remove redundant licensing model summary --- docs/COMMUNITY_AND_COMMERCIAL_MODEL.md | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 docs/COMMUNITY_AND_COMMERCIAL_MODEL.md diff --git a/docs/COMMUNITY_AND_COMMERCIAL_MODEL.md b/docs/COMMUNITY_AND_COMMERCIAL_MODEL.md deleted file mode 100644 index 443ebb4..0000000 --- a/docs/COMMUNITY_AND_COMMERCIAL_MODEL.md +++ /dev/null @@ -1,24 +0,0 @@ -# Community and Commercial Model - -## Community edition - -The public ARSVIN community edition is available under `GPL-3.0-or-later`. Users receive the rights and obligations stated in the GNU GPL and applicable third-party licenses. - -## Commercial agreement - -A separately negotiated agreement may provide additional rights or services for proprietary integration, OEM or white-label distribution, closed-source redistribution, private branches, warranty, maintenance, priority response, training, or engineering work. - -No commercial rights arise merely from the presence of `COMMERCIAL-LICENSE.md` in the repository. - -## Shared boundaries - -Both channels remain subject to: - -- rights actually controlled by the relevant copyright holder; -- third-party licenses and notices; -- applicable standards-access terms; -- trademark and branding restrictions; -- operational authorization and safety processes; and -- separately agreed warranties, validation scope, and acceptance criteria. - -The licensing channel does not change technical evidence into a certification, calibrated result, functional-safety approval, cybersecurity approval, or proof of external-device behavior. \ No newline at end of file From 6e7cfa887b435aa603c7142faae0704bc1613244 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:25:54 +0700 Subject: [PATCH 58/69] Remove redundant license summary document --- docs/CURRENT_LICENSE_SUMMARY.md | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 docs/CURRENT_LICENSE_SUMMARY.md diff --git a/docs/CURRENT_LICENSE_SUMMARY.md b/docs/CURRENT_LICENSE_SUMMARY.md deleted file mode 100644 index e5a18d6..0000000 --- a/docs/CURRENT_LICENSE_SUMMARY.md +++ /dev/null @@ -1,10 +0,0 @@ -# Current License Summary - -```text -Current community source and releases: GPL-3.0-or-later -Historical revisions through 9440f08b6909ef2dc93dd483cfdcb4e1e86077d0: Apache-2.0 -Historical branch: archive/apache-2.0-final -Proprietary, OEM, or white-label rights: separate negotiated commercial agreement -``` - -The commercial notice is not itself a license and grants no additional rights. Third-party components retain their applicable licenses. See [LICENSING.md](LICENSING.md) for the complete boundary. \ No newline at end of file From 9a73563914934c19e5ec2c9f060583ab73de6049 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:26:17 +0700 Subject: [PATCH 59/69] Consolidate legal and provenance documentation index --- docs/LEGAL_AND_PROVENANCE_INDEX.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/LEGAL_AND_PROVENANCE_INDEX.md b/docs/LEGAL_AND_PROVENANCE_INDEX.md index 7b4a8e5..5202ff4 100644 --- a/docs/LEGAL_AND_PROVENANCE_INDEX.md +++ b/docs/LEGAL_AND_PROVENANCE_INDEX.md @@ -1,7 +1,8 @@ # Legal and Provenance Index +Canonical repository records: + - [Current licensing model](LICENSING.md) -- [Current license summary](CURRENT_LICENSE_SUMMARY.md) - [License transition record](LICENSE_TRANSITION_RECORD_2026-07-14.md) - [Commercial licensing FAQ](COMMERCIAL_LICENSING_FAQ.md) - [Current package legal content](PACKAGE_LEGAL_CONTENT.md) From 3a73f420be63fa35a26d89e8629b35a0b428f163 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:26:42 +0700 Subject: [PATCH 60/69] Improve issue routing for security support and commercial inquiries --- .github/ISSUE_TEMPLATE/config.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 50d9bba..965e5dd 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,8 +1,14 @@ blank_issues_enabled: false contact_links: - - name: Security report + - name: Security vulnerability url: https://github.com/masarray/arsvin/security/advisories/new - about: Please report security issues privately. - - name: Support guide + about: Report vulnerabilities privately. Do not publish exploit or confidential evidence. + - name: Support and sanitization guide url: https://github.com/masarray/arsvin/blob/main/SUPPORT.md - about: Read what information to include in support requests. + about: Review environment details, evidence limits, and data-sanitization requirements before filing an issue. + - name: Commercial licensing + url: https://github.com/masarray/arsvin/blob/main/COMMERCIAL-LICENSE.md + about: Review the commercial licensing notice. Do not post confidential commercial or station information publicly. + - name: Product website + url: https://masarray.github.io/arsvin/ + about: Product overview, downloads, engineering documentation, and licensing model. \ No newline at end of file From 0ee93b828a3b73b3cc3c457657d18ee76ec477d8 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:27:08 +0700 Subject: [PATCH 61/69] Add concise transition implementation notes --- docs/LICENSE_TRANSITION_IMPLEMENTATION_NOTES.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 docs/LICENSE_TRANSITION_IMPLEMENTATION_NOTES.md diff --git a/docs/LICENSE_TRANSITION_IMPLEMENTATION_NOTES.md b/docs/LICENSE_TRANSITION_IMPLEMENTATION_NOTES.md new file mode 100644 index 0000000..9d79a7b --- /dev/null +++ b/docs/LICENSE_TRANSITION_IMPLEMENTATION_NOTES.md @@ -0,0 +1,11 @@ +# License Transition Implementation Notes + +The migration is implemented through repository files and automated gates rather than a destructive rewrite of Git history. + +- `archive/apache-2.0-final` preserves the final historical Apache revision. +- `main` after the transition uses `GPL-3.0-or-later` for current community source and releases. +- Commercial rights require a separate executed agreement. +- Current packages contain only the current GPL license plus notices and historical-boundary documentation. +- CI, Pages, build, installer, and release paths verify the model before publication. + +Historical commit messages and earlier releases may continue to describe the license that applied at that time. \ No newline at end of file From f5119d110d7251b786311ff615af450eb2c56c8f Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:27:34 +0700 Subject: [PATCH 62/69] Remove redundant transition implementation notes --- docs/LICENSE_TRANSITION_IMPLEMENTATION_NOTES.md | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 docs/LICENSE_TRANSITION_IMPLEMENTATION_NOTES.md diff --git a/docs/LICENSE_TRANSITION_IMPLEMENTATION_NOTES.md b/docs/LICENSE_TRANSITION_IMPLEMENTATION_NOTES.md deleted file mode 100644 index 9d79a7b..0000000 --- a/docs/LICENSE_TRANSITION_IMPLEMENTATION_NOTES.md +++ /dev/null @@ -1,11 +0,0 @@ -# License Transition Implementation Notes - -The migration is implemented through repository files and automated gates rather than a destructive rewrite of Git history. - -- `archive/apache-2.0-final` preserves the final historical Apache revision. -- `main` after the transition uses `GPL-3.0-or-later` for current community source and releases. -- Commercial rights require a separate executed agreement. -- Current packages contain only the current GPL license plus notices and historical-boundary documentation. -- CI, Pages, build, installer, and release paths verify the model before publication. - -Historical commit messages and earlier releases may continue to describe the license that applied at that time. \ No newline at end of file From a4b7c56cc8682999cb9f1f1d68704b1388f88524 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:27:53 +0700 Subject: [PATCH 63/69] Add commercial notice clarification --- docs/NOT_A_LICENSE.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/NOT_A_LICENSE.md diff --git a/docs/NOT_A_LICENSE.md b/docs/NOT_A_LICENSE.md new file mode 100644 index 0000000..26dbdae --- /dev/null +++ b/docs/NOT_A_LICENSE.md @@ -0,0 +1 @@ +This file should not exist. \ No newline at end of file From 902fda886d439788343a2f062d669cb03e3d1ab0 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:28:12 +0700 Subject: [PATCH 64/69] Remove accidental placeholder file --- docs/NOT_A_LICENSE.md | 1 - 1 file changed, 1 deletion(-) delete mode 100644 docs/NOT_A_LICENSE.md diff --git a/docs/NOT_A_LICENSE.md b/docs/NOT_A_LICENSE.md deleted file mode 100644 index 26dbdae..0000000 --- a/docs/NOT_A_LICENSE.md +++ /dev/null @@ -1 +0,0 @@ -This file should not exist. \ No newline at end of file From 2819ca0fcb1d2733f0594ecd407f3bfeac0eb7a3 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:28:27 +0700 Subject: [PATCH 65/69] noop --- docs/.keep-transition | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/.keep-transition diff --git a/docs/.keep-transition b/docs/.keep-transition new file mode 100644 index 0000000..a8b6c94 --- /dev/null +++ b/docs/.keep-transition @@ -0,0 +1 @@ +noop \ No newline at end of file From f7abaecbcb04722a442ac6b437acddde6f5e93ae Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:28:48 +0700 Subject: [PATCH 66/69] Remove accidental placeholder --- docs/.keep-transition | 1 - 1 file changed, 1 deletion(-) delete mode 100644 docs/.keep-transition diff --git a/docs/.keep-transition b/docs/.keep-transition deleted file mode 100644 index a8b6c94..0000000 --- a/docs/.keep-transition +++ /dev/null @@ -1 +0,0 @@ -noop \ No newline at end of file From 77a0378c4b1feb5aba02fd3ffffe4195e09e2785 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:29:03 +0700 Subject: [PATCH 67/69] temporary --- docs/ignore-this | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/ignore-this diff --git a/docs/ignore-this b/docs/ignore-this new file mode 100644 index 0000000..ca4a8f8 --- /dev/null +++ b/docs/ignore-this @@ -0,0 +1 @@ +temporary \ No newline at end of file From d3b0d7be63fc1c505169e3f3e997c20b3b55199a Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:29:21 +0700 Subject: [PATCH 68/69] Remove accidental temporary file --- docs/ignore-this | 1 - 1 file changed, 1 deletion(-) delete mode 100644 docs/ignore-this diff --git a/docs/ignore-this b/docs/ignore-this deleted file mode 100644 index ca4a8f8..0000000 --- a/docs/ignore-this +++ /dev/null @@ -1 +0,0 @@ -temporary \ No newline at end of file From 828dc8377c167802fd176254e4d2a779be19f160 Mon Sep 17 00:00:00 2001 From: masarray Date: Tue, 14 Jul 2026 18:35:27 +0700 Subject: [PATCH 69/69] Fix generated documentation links and root references --- scripts/public_site_builder.py | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/scripts/public_site_builder.py b/scripts/public_site_builder.py index 9c4d238..442c3fa 100644 --- a/scripts/public_site_builder.py +++ b/scripts/public_site_builder.py @@ -66,6 +66,16 @@ def metadata(path: Path) -> tuple[str, str]: return title, description +def repository_reference(path: str, fragment: str = "") -> str: + normalized = path.replace("\\", "/").lstrip("/") + while normalized.startswith("../"): + normalized = normalized[3:] + while normalized.startswith("./"): + normalized = normalized[2:] + mode = "blob" if Path(normalized).suffix else "tree" + return f"{REPO_URL}/{mode}/main/{normalized}{fragment}" + + def rewrite_link(target: str, current_slug: str, docs: dict[str, DocPage]) -> str: target = html.unescape(target.strip()) if not target or target.startswith("#"): @@ -76,13 +86,19 @@ def rewrite_link(target: str, current_slug: str, docs: dict[str, DocPage]) -> st parsed = urlsplit(target) path = parsed.path.replace("\\", "/") fragment = f"#{parsed.fragment}" if parsed.fragment else "" + normalized = path + while normalized.startswith("./"): + normalized = normalized[2:] + + if normalized.startswith("../site/"): + relative_asset = normalized[len("../site/") :] + prefix = "../" if current_slug == "index" else "../../" + return f"{prefix}{relative_asset}{fragment}" - if path.endswith(".md"): - normalized = path - while normalized.startswith("./"): - normalized = normalized[2:] - if normalized.startswith("../"): - return f"{REPO_URL}/blob/main/{normalized[3:]}{fragment}" + if normalized.startswith("../"): + return repository_reference(normalized, fragment) + + if normalized.endswith(".md"): name = Path(normalized).name page = docs.get(name) if page: @@ -93,8 +109,9 @@ def rewrite_link(target: str, current_slug: str, docs: dict[str, DocPage]) -> st return base + fragment return f"{REPO_URL}/blob/main/docs/{normalized}{fragment}" - if path.startswith("samples/") or path.startswith("src/"): - return f"{REPO_URL}/tree/main/{path}{fragment}" + if normalized.startswith(("samples/", "src/", "tests/", "scripts/", "installer/", ".github/")): + return repository_reference(normalized, fragment) + return target