diff --git a/.github/workflows/determinism.yml b/.github/workflows/determinism.yml index 16cef58..8a4d286 100644 --- a/.github/workflows/determinism.yml +++ b/.github/workflows/determinism.yml @@ -1,38 +1,93 @@ name: Determinism Check on: - pull_request: - branches: [main] push: - branches: [main] - -env: - LC_ALL: C - TZ: UTC + pull_request: jobs: determinism: runs-on: ubuntu-latest steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - - name: Determinism (stdout) - shell: bash + - uses: actions/checkout@v4 + + - name: Test empty stdin → deterministic INVALID run: | - set -euo pipefail - TOOL="./guillotine.sh" - if [ ! -f "$TOOL" ]; then - echo "FAIL: tool not found: $TOOL" - ls -la - exit 2 + set -eu + EXIT_CODE=0 + ./guillotine.sh < /dev/null > output.txt 2>&1 || EXIT_CODE=$? + + if [ "$EXIT_CODE" -eq 0 ]; then + echo "FAIL: Empty stdin should not succeed" + exit 1 fi - chmod +x "$TOOL" || true - out1="$(mktemp)"; out2="$(mktemp)" - ("$TOOL" || true) | tr -d "\r" > "$out1" - ("$TOOL" || true) | tr -d "\r" > "$out2" - if ! cmp -s "$out1" "$out2"; then - echo "FAIL: nondeterministic stdout for $TOOL" - echo "--- run1"; sed -n "1,200p" "$out1" || true - echo "--- run2"; sed -n "1,200p" "$out2" || true + echo "PASS: Empty stdin rejected with exit code $EXIT_CODE" + + - name: Test determinism (run twice) + run: | + set -eu + echo "test input" | ./guillotine.sh > output1.txt 2>&1 || true + echo $? > exit1.txt + + echo "test input" | ./guillotine.sh > output2.txt 2>&1 || true + echo $? > exit2.txt + + if ! diff output1.txt output2.txt; then + echo "FAIL: stdout differs" + exit 1 + fi + + if ! diff exit1.txt exit2.txt; then + echo "FAIL: exit code differs" + exit 1 + fi + + echo "PASS: determinism verified" + + - name: Test no state mutation + run: | + set -eu + TMPDIR="${RUNNER_TEMP:-/tmp}/guillotine-mut-${RANDOM}" + mkdir -p "$TMPDIR" + cp -f ./guillotine.sh "$TMPDIR/" + cd "$TMPDIR" + chmod +x ./guillotine.sh + + BEFORE="$(mktemp)" + AFTER="$(mktemp)" + find . -maxdepth 1 -type f | LC_ALL=C sort > "$BEFORE" + echo "test" | ./guillotine.sh > /dev/null 2>&1 || true + find . -maxdepth 1 -type f | LC_ALL=C sort > "$AFTER" + + if ! diff "$BEFORE" "$AFTER"; then + echo "FAIL: filesystem mutated" + exit 1 + fi + + echo "PASS: no state mutation" + + - name: Test env isolation + run: | + set -eu + env | sort > env_before.txt + echo "test" | ./guillotine.sh > /dev/null 2>&1 || true + env | sort > env_after.txt + + if ! diff env_before.txt env_after.txt; then + echo "FAIL: environment mutated" + exit 1 + fi + echo "PASS: no env mutation" + + version-lock: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Verify VERSION is locked at v0.0.0 + run: | + VERSION=$(head -1 VERSION) + if [ "$VERSION" != "v0.0.0" ]; then + echo "FAIL: VERSION must be v0.0.0, got $VERSION" exit 1 fi - echo "PASS: deterministic stdout for $TOOL" + echo "PASS: VERSION locked at v0.0.0" diff --git a/LICENSE b/LICENSE index 3e575bd..c04745e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,94 +1,21 @@ - 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. - - "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. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License. - - "Derivative Works" shall mean any work that is based on (or derived - from) the Work. - - "Contribution" shall mean any work intentionally submitted for - inclusion in the Work. - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received. - - 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. - - 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. - - 4. Redistribution. - You may reproduce and distribute copies of the Work or Derivative - Works provided that You: - (a) give recipients a copy of this License; and - (b) mark modified files; and - (c) retain notices; and - (d) include NOTICE contents if present. - - 5. Submission of Contributions. - Contributions submitted for inclusion in the Work are under this - License unless explicitly stated otherwise. - - 6. Trademarks. - This License does not grant permission to use trade names, trademarks, - service marks, or product names of the Licensor. - - 7. Disclaimer of Warranty. - The Work is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. - - 8. Limitation of Liability. - In no event shall any Contributor be liable for any damages arising - from the use of the Work. - - 9. Accepting Warranty or Additional Liability. - You may offer support or warranty only on Your own behalf. - - END OF TERMS AND CONDITIONS - - Copyright 2026 midiakiasat - - 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. +MIT License + +Copyright (c) 2026 Verifrax + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.