diff --git a/.agents/skills/reverse-engineer-anything/references/native-and-artifacts.md b/.agents/skills/reverse-engineer-anything/references/native-and-artifacts.md index 21cc459ad..ef0ad03b4 100644 --- a/.agents/skills/reverse-engineer-anything/references/native-and-artifacts.md +++ b/.agents/skills/reverse-engineer-anything/references/native-and-artifacts.md @@ -119,6 +119,8 @@ loaded bytes, file mappings, relocations and the entry against the immutable snapshot. Keep `mismatch` and `unsupported` explicit. Verified import covers the reported static image, not runtime DOS or PC-98 hardware behavior. +For Ghidra decompilation, `procedure_pseudo_code` also accepts `procedure: "file-offset:0x..."`; CLI `rea decompile --file-offset=0x... --provider ghidra` resolves the source byte offset internally. An unresolved 0x-prefixed numeric procedure selector also falls back to a unique file mapping. Existing symbols and analysis addresses win; multiple mappings fail as ambiguous. Preserve the returned file-offset and address locations and raw selection observations. ELF virtual addresses are distinct from file offsets; never assume an arbitrary offset plus image base is an analysis address. + Use `read_bytes` for initialized analysis memory and `address_to_file_offset` to anchor one observed address to original file bytes. Loader fixups can change a word; a source offset does not imply byte equality. Complete function body ranges diff --git a/.github/actions/portable-build-cache/action.yml b/.github/actions/portable-build-cache/action.yml index ad127ce3d..cee775ec5 100644 --- a/.github/actions/portable-build-cache/action.yml +++ b/.github/actions/portable-build-cache/action.yml @@ -1,14 +1,24 @@ name: Portable build cache -description: Reuse Turbo build outputs without serializing verification jobs. +description: Restore portable Turbo build outputs from the current run or cross-run cache. inputs: save: description: Save newly built outputs after the job succeeds. default: "false" + build_cache_artifact: + description: Reuse portable Turbo outputs uploaded by the current workflow run. + default: "" runs: using: composite steps: + - name: Download portable build outputs from this workflow run + if: inputs.build_cache_artifact != '' + uses: actions/download-artifact@v4 + with: + name: ${{ inputs.build_cache_artifact }} + path: .turbo/cache/ - name: Resolve portable build task hashes id: plan + if: inputs.build_cache_artifact == '' shell: bash env: BUILD_CACHE_PREFIX: rea-portable-build-v2-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.npmrc', '.nvmrc', 'package-lock.json') }} @@ -28,14 +38,14 @@ runs: console.log(`prefix=${process.env.BUILD_CACHE_PREFIX}-`); ' >> "$GITHUB_OUTPUT" - name: Restore portable build outputs - if: inputs.save != 'true' + if: inputs.build_cache_artifact == '' && inputs.save != 'true' uses: actions/cache/restore@v4 with: path: .turbo/cache/ key: ${{ steps.plan.outputs.key }} restore-keys: ${{ steps.plan.outputs.prefix }} - name: Restore and save portable build outputs - if: inputs.save == 'true' + if: inputs.build_cache_artifact == '' && inputs.save == 'true' uses: actions/cache@v4 with: path: .turbo/cache/ diff --git a/.github/workflows/ci-full-pr.yml b/.github/workflows/ci-full-pr.yml new file mode 100644 index 000000000..8f76a2ea2 --- /dev/null +++ b/.github/workflows/ci-full-pr.yml @@ -0,0 +1,18 @@ +name: Full PR qualification + +on: + pull_request: + branches: [main, "release/*"] + types: [labeled] + +permissions: + contents: read + actions: read + +jobs: + qualification: + name: Qualify labeled PR revision + if: github.event.label.name == 'ci:full' + uses: ./.github/workflows/ci.yml + with: + source_sha: ${{ github.sha }} diff --git a/.github/workflows/ci-timings.yml b/.github/workflows/ci-timings.yml new file mode 100644 index 000000000..30fa19464 --- /dev/null +++ b/.github/workflows/ci-timings.yml @@ -0,0 +1,46 @@ +name: CI timings + +on: + schedule: + - cron: "17 * * * *" + workflow_dispatch: + +concurrency: + group: ci-timings-${{ github.repository }} + cancel-in-progress: false + +permissions: + contents: read + actions: read + +jobs: + report: + name: Collect recent completed workflow attempts + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + # Consume only API data and execute batch code from the trusted default branch. + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.repository.default_branch }} + persist-credentials: false + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + - name: Record queue, execution, and matched step timing + continue-on-error: true + env: + GH_TOKEN: ${{ github.token }} + CI_REPOSITORY: ${{ github.repository }} + run: node scripts/ci/job-timings-batch.mjs + - name: Upload CI timing artifacts + if: always() && hashFiles('.cache/ci-job-timings/*') != '' + continue-on-error: true + uses: actions/upload-artifact@v4 + with: + name: ci-job-timings-batch + path: .cache/ci-job-timings/ + include-hidden-files: true + if-no-files-found: error + overwrite: true + retention-days: 14 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7f7f5f0b..17ff83d08 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,42 +5,44 @@ on: branches: [main] pull_request: branches: [main, "release/*"] + schedule: + - cron: "23 0-2,4-23 * * *" + - cron: "23 3 * * *" workflow_dispatch: + workflow_call: + inputs: + source_sha: + description: Exact qualification source; must match the caller revision. + required: true + type: string permissions: contents: read concurrency: - group: ci-${{ github.event.pull_request.number || github.ref }} - # The latest main push verifies the full tree, including earlier changes. - # Publication uses its own release workflow and concurrency group. - cancel-in-progress: true + # Complete qualification finishes even while main receives more pushes. + # Main feedback also finishes, coalescing newer pushes to one pending run. + # Scheduled/manual main runs coalesce to one active and the latest pending; + # release and label-triggered qualification use exact-revision groups. + group: ci-${{ (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || inputs.source_sha != '' || contains(github.event.pull_request.labels.*.name, 'ci:full')) && 'qualification' || 'feedback' }}-${{ inputs.source_sha || github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' && inputs.source_sha == '' && !contains(github.event.pull_request.labels.*.name, 'ci:full') }} env: HUSKY: "0" jobs: - pr-title: - name: Conventional PR title - if: github.event_name == 'pull_request' - runs-on: ubuntu-latest - steps: - - name: Validate title for Release Please - env: - PR_TITLE: ${{ github.event.pull_request.title }} - run: >- - node -e 'const title = process.env.PR_TITLE ?? ""; - const conventional = /^(?:feat|fix|docs|refactor|perf|test|build|ci|chore|revert)(?:\([a-z0-9._/-]+\))?!?: .+/u; - if (!conventional.test(title)) { - console.error("PR title must use Conventional Commits, for example: feat: add historical source import"); - process.exit(1); - }' - changes: name: Classify changes runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: read + actions: read outputs: + tier: ${{ steps.plan.outputs.tier }} + qualification_run_id: ${{ steps.qualification.outputs.run_id }} code: ${{ steps.plan.outputs.code }} + sqlite: ${{ steps.plan.outputs.sqlite }} runtime: ${{ steps.plan.outputs.runtime }} package: ${{ steps.plan.outputs.package }} apple: ${{ steps.plan.outputs.apple }} @@ -59,26 +61,58 @@ jobs: nativeaot: ${{ steps.plan.outputs.nativeaot }} website: ${{ steps.plan.outputs.website }} matrix: ${{ steps.plan.outputs.matrix }} + test_selection: ${{ steps.plan.outputs.test_selection }} steps: - uses: actions/checkout@v4 with: + ref: ${{ inputs.source_sha || github.sha }} fetch-depth: 0 - uses: actions/setup-node@v4 with: node-version-file: .nvmrc + - name: Bind qualification to the caller revision + if: inputs.source_sha != '' + env: + SOURCE_SHA: ${{ inputs.source_sha }} + run: | + test "${SOURCE_SHA}" = "${GITHUB_SHA}" + test "${SOURCE_SHA}" = "$(git rev-parse HEAD)" + - name: Find a verified ancestor for push selection + id: baseline + if: github.event_name == 'push' && inputs.source_sha == '' + env: + GH_TOKEN: ${{ github.token }} + HEAD_SHA: ${{ github.sha }} + CI_REPOSITORY: ${{ github.repository }} + CI_DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + run: node scripts/ci/baseline.mjs + - name: Admit scheduled full qualification + id: qualification + if: github.event_name == 'schedule' && inputs.source_sha == '' + env: + GH_TOKEN: ${{ github.token }} + HEAD_SHA: ${{ github.sha }} + CI_REPOSITORY: ${{ github.repository }} + CI_REPOSITORY_ID: ${{ github.repository_id }} + CI_DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + CI_FORCE_FULL: ${{ github.event.schedule == '23 3 * * *' }} + run: node scripts/ci/qualification.mjs - name: Select verification lanes id: plan env: - BASE_SHA: ${{ github.event.pull_request.base.sha }} - HEAD_SHA: ${{ github.event.pull_request.head.sha }} - CI_FULL: ${{ contains(github.event.pull_request.labels.*.name, 'ci:full') }} + BASE_SHA: ${{ steps.baseline.outputs.base || github.event.pull_request.base.sha }} + BASELINE_REASON: ${{ steps.baseline.outputs.reason }} + HEAD_SHA: ${{ inputs.source_sha || github.event.pull_request.head.sha || github.sha }} + CI_FULL: ${{ inputs.source_sha != '' || contains(github.event.pull_request.labels.*.name, 'ci:full') }} + CI_SKIP_FULL: ${{ steps.qualification.outputs.run_full == 'false' }} run: node scripts/ci/plan.mjs static: name: Static checks needs: changes - if: ${{ !cancelled() }} + if: ${{ !cancelled() && needs.changes.outputs.tier != 'reused' }} runs-on: ubuntu-latest + timeout-minutes: 10 steps: - name: Require successful change classification env: @@ -90,6 +124,9 @@ jobs: node-version-file: .nvmrc cache: npm - run: npm ci + - name: Validate workflow syntax and expressions + if: needs.changes.outputs.workflows == 'true' + run: go run github.com/rhysd/actionlint/cmd/actionlint@v1.7.7 -shellcheck= -pyflakes= - if: needs.changes.outputs.code == 'true' run: npm run check:ci - if: needs.changes.outputs.code == 'true' @@ -114,6 +151,7 @@ jobs: needs: [changes, build] if: needs.changes.outputs.code == 'true' runs-on: ubuntu-latest + timeout-minutes: 30 strategy: fail-fast: false matrix: @@ -129,7 +167,14 @@ jobs: with: name: rea-test-runtime path: . - - run: npm run test:ci:shard:run -- --shard=${{ matrix.shard }} + - name: Run complete portable suite with coverage + if: needs.changes.outputs.tier == 'full' + run: npm run test:ci:shard:run -- --shard=${{ matrix.shard }} + env: + REA_CI_TEST_HISTORY: .cache/ci-test-history/test-results.json + - name: Run complete portable suite for fast feedback + if: needs.changes.outputs.tier == 'fast' + run: npm run test:run -- --reporter=default --reporter=blob --shard=${{ matrix.shard }} env: REA_CI_TEST_HISTORY: .cache/ci-test-history/test-results.json - uses: actions/upload-artifact@v4 @@ -145,8 +190,20 @@ jobs: build: name: Build package needs: changes - if: needs.changes.outputs.code == 'true' + # Reusable provider workflows consume this run's portable build artifact, + # even when a workflow-only edit selects the lane without portable tests. + if: >- + needs.changes.outputs.code == 'true' || + needs.changes.outputs.browser == 'true' || + needs.changes.outputs.binary_layout == 'true' || + needs.changes.outputs.evm == 'true' || + needs.changes.outputs.javascript_recovery == 'true' || + needs.changes.outputs.recorded_crash == 'true' || + needs.changes.outputs.web_network == 'true' || + needs.changes.outputs.web_runtime == 'true' || + needs.changes.outputs.web_source_map == 'true' runs-on: ubuntu-latest + timeout-minutes: 10 permissions: contents: read actions: read @@ -160,21 +217,17 @@ jobs: - name: Reuse portable build outputs across runs uses: ./.github/actions/portable-build-cache with: - save: "true" + save: ${{ github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }} - run: npm run test:prepare - - name: Find successful default-branch timing history + - name: Find available trusted full-suite timing history id: history continue-on-error: true env: GH_TOKEN: ${{ github.token }} CI_REPOSITORY: ${{ github.repository }} + CI_REPOSITORY_ID: ${{ github.repository_id }} CI_DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} - run: | - run_id="$(gh api --method GET \ - "repos/${CI_REPOSITORY}/actions/workflows/ci.yml/runs" \ - -f branch="${CI_DEFAULT_BRANCH}" -f event=push -f status=success -f per_page=1 \ - --jq '.workflow_runs[0].id // empty')" - echo "run-id=${run_id}" >> "${GITHUB_OUTPUT}" + run: node scripts/ci/test-history.mjs - name: Download previous timing report if: steps.history.outputs.run-id != '' continue-on-error: true @@ -210,15 +263,18 @@ jobs: retention-days: 7 sqlite-runtime: - needs: [changes, build] - if: needs.changes.outputs.code == 'true' + # Preserve all selected coverage, but admit expensive host/provider work + # only after static validation. Portable tests still provide early feedback. + needs: [changes, static, build] + if: needs.changes.outputs.sqlite == 'true' uses: ./.github/workflows/sqlite-runtime.yml test: - name: Test (coverage + timing) + name: Portable tests needs: [changes, test-shard] - if: ${{ !cancelled() }} + if: ${{ !cancelled() && needs.changes.outputs.tier != 'reused' }} runs-on: ubuntu-latest + timeout-minutes: 10 steps: - name: Require successful change classification env: @@ -241,7 +297,7 @@ jobs: merge-multiple: true - name: Merge coverage, JUnit, and timing reports id: merge - if: needs.changes.outputs.code == 'true' && success() + if: needs.changes.outputs.code == 'true' && needs.changes.outputs.tier == 'full' && success() run: >- npm run test:ci:merge -- --coverage.reportsDirectory=coverage @@ -251,13 +307,28 @@ jobs: --reporter=default --reporter=junit --reporter=json + --reporter=./scripts/ci/test-timing-reporter.mjs + --outputFile.junit=test-results.xml + --outputFile.json=test-results.json + - name: Merge fast-suite JUnit and timing reports + id: merge-fast + if: needs.changes.outputs.code == 'true' && needs.changes.outputs.tier == 'fast' && success() + run: >- + npm exec -- vitest --merge-reports + --reporter=default + --reporter=junit + --reporter=json + --reporter=./scripts/ci/test-timing-reporter.mjs --outputFile.junit=test-results.xml --outputFile.json=test-results.json - name: Summarize slowest test files - if: needs.changes.outputs.code == 'true' && !cancelled() && hashFiles('test-results.json') != '' + if: needs.changes.outputs.code == 'true' && !cancelled() && hashFiles('test-timings.json') != '' env: SHARD_RESULT: ${{ needs.test-shard.result }} - MERGE_RESULT: ${{ steps.merge.outcome }} + MERGE_RESULT: ${{ needs.changes.outputs.tier == 'full' && steps.merge.outcome || steps.merge-fast.outcome }} + CI_VERIFY_TEST_INVENTORY: "true" + CI_TEST_SELECTION: ${{ needs.changes.outputs.test_selection }} + CI_PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: node scripts/ci/test-report.mjs - uses: actions/upload-artifact@v4 if: needs.changes.outputs.code == 'true' && !cancelled() && hashFiles('test-results.json') != '' @@ -266,11 +337,14 @@ jobs: path: | test-results.xml test-results.json + test-timings.json coverage/ + .cache/ci-test-selection/report.json + include-hidden-files: true if-no-files-found: error retention-days: 30 - name: Publish successful timing history - if: needs.changes.outputs.code == 'true' && success() && needs.test-shard.result == 'success' + if: needs.changes.outputs.code == 'true' && needs.changes.outputs.tier == 'full' && success() && needs.test-shard.result == 'success' uses: actions/upload-artifact@v4 with: name: test-timings @@ -287,7 +361,7 @@ jobs: conformance-fixtures: name: Source-built conformance fixtures - needs: changes + needs: [changes, static] if: needs.changes.outputs.fixtures == 'true' runs-on: ubuntu-latest timeout-minutes: 10 @@ -298,7 +372,7 @@ jobs: windows-native-build: name: Build bundled Windows x64 native controls - needs: changes + needs: [changes, static] if: needs.changes.outputs.runtime == 'true' runs-on: ubuntu-latest timeout-minutes: 10 @@ -334,7 +408,7 @@ jobs: package-e2e: name: Native package baseline (${{ matrix.platform }} ${{ matrix.architecture }}) - needs: [changes, build, windows-native-build] + needs: [changes, static, build, windows-native-build] if: needs.changes.outputs.runtime == 'true' strategy: fail-fast: false @@ -373,6 +447,8 @@ jobs: name: windows-native-controls path: native/windows/build/ - run: npm run verify:windows-native:artifact + - name: Verify NativeAOT diagnostic applicability on this host + run: npm run test:focused -- tests/evaluation/package/nativeAotDiagnostics.test.ts - name: Resolve npm cache before verifier HOME isolation id: npm-cache run: | @@ -381,13 +457,24 @@ jobs: - run: npm run verify:package env: npm_config_cache: ${{ steps.npm-cache.outputs.path }} + REA_VERIFIED_PACKAGE_DIRECTORY: ${{ needs.changes.outputs.tier == 'full' && matrix.platform == 'linux' && matrix.architecture == 'x64' && '.cache/verified-package' || '' }} - name: Verify real Node Inspector discovery and observation timeout-minutes: 10 run: npm run verify:inspector + - name: Retain the exact qualified release package + if: needs.changes.outputs.tier == 'full' && matrix.platform == 'linux' && matrix.architecture == 'x64' + uses: actions/upload-artifact@v4 + with: + name: verified-release-package + path: .cache/verified-package/ + include-hidden-files: true + if-no-files-found: error + overwrite: true + retention-days: 7 apple-artifacts: name: Real Apple artifact CLI/MCP E2E - needs: [changes, build] + needs: [changes, static, build] if: needs.changes.outputs.apple == 'true' runs-on: macos-15 timeout-minutes: 15 @@ -442,7 +529,7 @@ jobs: reconstruction-readiness: name: Reconstruction readiness - needs: changes + needs: [changes, static] if: needs.changes.outputs.readiness == 'true' runs-on: ubuntu-latest timeout-minutes: 15 @@ -471,7 +558,7 @@ jobs: windows-curated: name: Windows capability and package lane - needs: [changes, build, windows-native-build] + needs: [changes, static, build, windows-native-build] if: needs.changes.outputs.package == 'true' runs-on: windows-latest timeout-minutes: 25 @@ -583,6 +670,7 @@ jobs: needs: changes if: needs.changes.outputs.docs == 'true' runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -602,73 +690,78 @@ jobs: skills/reverse-engineer-anything if-no-files-found: error - workflows: - name: Validate workflows - needs: changes - if: needs.changes.outputs.workflows == 'true' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Validate workflow syntax and expressions - run: go run github.com/rhysd/actionlint/cmd/actionlint@v1.7.7 -shellcheck= -pyflakes= - browser: - needs: changes + needs: [changes, static, build] if: needs.changes.outputs.browser == 'true' uses: ./.github/workflows/real-browser.yml + with: + build_cache_artifact: rea-build-cache binary_layout: - needs: changes + needs: [changes, static, build] if: needs.changes.outputs.binary_layout == 'true' uses: ./.github/workflows/real-binary-layout.yml + with: + build_cache_artifact: rea-build-cache evm: - needs: changes + needs: [changes, static, build] if: needs.changes.outputs.evm == 'true' uses: ./.github/workflows/real-evm-interface.yml + with: + build_cache_artifact: rea-build-cache javascript_recovery: - needs: changes + needs: [changes, static, build] if: needs.changes.outputs.javascript_recovery == 'true' uses: ./.github/workflows/real-javascript-recovery.yml + with: + build_cache_artifact: rea-build-cache recorded_crash: - needs: changes + needs: [changes, static, build] if: needs.changes.outputs.recorded_crash == 'true' uses: ./.github/workflows/real-recorded-crash.yml + with: + build_cache_artifact: rea-build-cache web_network: - needs: changes + needs: [changes, static, build] if: needs.changes.outputs.web_network == 'true' uses: ./.github/workflows/real-web-network-captures.yml + with: + build_cache_artifact: rea-build-cache web_runtime: - needs: changes + needs: [changes, static, build] if: needs.changes.outputs.web_runtime == 'true' uses: ./.github/workflows/real-web-runtime.yml + with: + build_cache_artifact: rea-build-cache web_source_map: - needs: changes + needs: [changes, static, build] if: needs.changes.outputs.web_source_map == 'true' uses: ./.github/workflows/real-web-source-map.yml + with: + build_cache_artifact: rea-build-cache nativeaot: - needs: changes + needs: [changes, static] if: needs.changes.outputs.nativeaot == 'true' uses: ./.github/workflows/nativeaot-fixtures.yml website: - needs: changes + needs: [changes, static] if: needs.changes.outputs.website == 'true' uses: ./.github/workflows/website-check.yml required: name: CI required - if: ${{ !cancelled() }} + if: ${{ always() }} needs: [ changes, - pr-title, static, build, test-shard, @@ -681,7 +774,6 @@ jobs: reconstruction-readiness, windows-curated, docs, - workflows, browser, binary_layout, evm, @@ -694,12 +786,24 @@ jobs: website, ] runs-on: ubuntu-latest + timeout-minutes: 5 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version-file: .nvmrc - name: Require every selected lane to pass + id: gate env: CI_JOBS: ${{ toJSON(needs) }} + CI_QUALIFICATION_DIRECTORY: .cache/ci-qualification run: node scripts/ci/required.mjs + - name: Upload full qualification receipt artifact + if: needs.changes.outputs.tier == 'full' && success() + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.gate.outputs.receipt_name }} + path: ${{ steps.gate.outputs.receipt_path }} + if-no-files-found: error + overwrite: true + retention-days: 7 diff --git a/.github/workflows/nativeaot-fixtures.yml b/.github/workflows/nativeaot-fixtures.yml index e819ca5fb..ce7dc1ea1 100644 --- a/.github/workflows/nativeaot-fixtures.yml +++ b/.github/workflows/nativeaot-fixtures.yml @@ -12,7 +12,8 @@ jobs: name: Build Windows x64 NativeAOT fixture # .NET 8.0.22's bundled linker discovery supports VS 2019/2022. runs-on: windows-2022 - timeout-minutes: 15 + # Two bounded restore attempts and one compile can each take five minutes. + timeout-minutes: 20 env: DOTNET_CLI_TELEMETRY_OPTOUT: "1" DOTNET_PROCESSOR_COUNT: "1" diff --git a/.github/workflows/pr-title.yml b/.github/workflows/pr-title.yml new file mode 100644 index 000000000..abe98bb48 --- /dev/null +++ b/.github/workflows/pr-title.yml @@ -0,0 +1,29 @@ +name: PR title + +on: + pull_request: + branches: [main, "release/*"] + types: [opened, synchronize, reopened, edited] + +permissions: {} + +concurrency: + group: pr-title-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + pr-title: + name: Conventional PR title + runs-on: ubuntu-latest + timeout-minutes: 2 + steps: + - name: Validate title for Release Please + env: + PR_TITLE: ${{ github.event.pull_request.title }} + run: >- + node -e 'const title = process.env.PR_TITLE ?? ""; + const conventional = /^(?:feat|fix|docs|refactor|perf|test|build|ci|chore|revert)(?:\([a-z0-9._/-]+\))?!?: .+/u; + if (!conventional.test(title)) { + console.error("PR title must use Conventional Commits, for example: feat: add historical source import"); + process.exit(1); + }' diff --git a/.github/workflows/real-binary-layout.yml b/.github/workflows/real-binary-layout.yml index e8c244de6..5cec952ce 100644 --- a/.github/workflows/real-binary-layout.yml +++ b/.github/workflows/real-binary-layout.yml @@ -8,14 +8,16 @@ on: type: boolean default: false workflow_call: + inputs: + build_cache_artifact: + description: Portable build cache artifact from the calling CI run. + required: false + type: string + default: "" permissions: contents: read -concurrency: - group: real-binary-layout-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - env: NODE_OPTIONS: --max-old-space-size=768 HUSKY: "0" @@ -33,6 +35,8 @@ jobs: cache: npm - run: npm ci - uses: ./.github/actions/portable-build-cache + with: + build_cache_artifact: ${{ inputs.build_cache_artifact }} - name: Acquire exact upstream libraries in an isolated runner environment shell: bash run: | diff --git a/.github/workflows/real-browser.yml b/.github/workflows/real-browser.yml index 76ba2e4a6..912fdafb1 100644 --- a/.github/workflows/real-browser.yml +++ b/.github/workflows/real-browser.yml @@ -2,12 +2,14 @@ name: Real browser verification on: workflow_call: + inputs: + build_cache_artifact: + description: Portable build cache artifact from the calling CI run. + required: false + type: string + default: "" workflow_dispatch: -concurrency: - group: real-browser-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - env: HUSKY: "0" @@ -26,6 +28,8 @@ jobs: cache: npm - run: npm ci - uses: ./.github/actions/portable-build-cache + with: + build_cache_artifact: ${{ inputs.build_cache_artifact }} - run: npm run verify:browser env: REA_BROWSER_EXECUTABLE: /usr/bin/google-chrome diff --git a/.github/workflows/real-evm-interface.yml b/.github/workflows/real-evm-interface.yml index 9e4cddeb4..dfdd3970f 100644 --- a/.github/workflows/real-evm-interface.yml +++ b/.github/workflows/real-evm-interface.yml @@ -3,14 +3,16 @@ name: Real offline EVM interface on: workflow_dispatch: workflow_call: + inputs: + build_cache_artifact: + description: Portable build cache artifact from the calling CI run. + required: false + type: string + default: "" permissions: contents: read -concurrency: - group: real-evm-interface-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - env: NODE_OPTIONS: --max-old-space-size=768 HUSKY: "0" @@ -27,6 +29,8 @@ jobs: cache: npm - run: npm ci - uses: ./.github/actions/portable-build-cache + with: + build_cache_artifact: ${{ inputs.build_cache_artifact }} - name: Acquire unchanged fixture compiler in isolated runner storage shell: bash run: | diff --git a/.github/workflows/real-javascript-recovery.yml b/.github/workflows/real-javascript-recovery.yml index 4fee667d8..817dc4dc0 100644 --- a/.github/workflows/real-javascript-recovery.yml +++ b/.github/workflows/real-javascript-recovery.yml @@ -2,15 +2,17 @@ name: Real JavaScript recovery on: workflow_call: + inputs: + build_cache_artifact: + description: Portable build cache artifact from the calling CI run. + required: false + type: string + default: "" workflow_dispatch: permissions: contents: read -concurrency: - group: javascript-recovery-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - env: HUSKY: "0" NODE_OPTIONS: "--max-old-space-size=768" @@ -28,6 +30,8 @@ jobs: cache: npm - run: npm ci - uses: ./.github/actions/portable-build-cache + with: + build_cache_artifact: ${{ inputs.build_cache_artifact }} - name: Fetch pinned Wakaru release into the job workspace shell: bash run: | diff --git a/.github/workflows/real-recorded-crash.yml b/.github/workflows/real-recorded-crash.yml index d4410bb24..04467a608 100644 --- a/.github/workflows/real-recorded-crash.yml +++ b/.github/workflows/real-recorded-crash.yml @@ -3,14 +3,16 @@ name: Real recorded crash evidence on: workflow_dispatch: workflow_call: + inputs: + build_cache_artifact: + description: Portable build cache artifact from the calling CI run. + required: false + type: string + default: "" permissions: contents: read -concurrency: - group: real-recorded-crash-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - env: NODE_OPTIONS: --max-old-space-size=768 HUSKY: "0" @@ -30,6 +32,8 @@ jobs: cache: npm - run: npm ci - uses: ./.github/actions/portable-build-cache + with: + build_cache_artifact: ${{ inputs.build_cache_artifact }} - name: Install GDB on the disposable CI runner shell: bash run: | diff --git a/.github/workflows/real-web-network-captures.yml b/.github/workflows/real-web-network-captures.yml index b888674f7..d41bb37a5 100644 --- a/.github/workflows/real-web-network-captures.yml +++ b/.github/workflows/real-web-network-captures.yml @@ -3,14 +3,16 @@ name: Real historical web network captures on: workflow_dispatch: workflow_call: + inputs: + build_cache_artifact: + description: Portable build cache artifact from the calling CI run. + required: false + type: string + default: "" permissions: contents: read -concurrency: - group: real-web-network-captures-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - env: HUSKY: "0" NODE_OPTIONS: --max-old-space-size=768 @@ -29,6 +31,8 @@ jobs: run: npm install --global npm@11.16.0 - run: npm ci - uses: ./.github/actions/portable-build-cache + with: + build_cache_artifact: ${{ inputs.build_cache_artifact }} - name: Acquire fixed upstream native profile in runner temporary storage shell: bash run: | diff --git a/.github/workflows/real-web-runtime.yml b/.github/workflows/real-web-runtime.yml index c600e895c..2575c55f9 100644 --- a/.github/workflows/real-web-runtime.yml +++ b/.github/workflows/real-web-runtime.yml @@ -1,12 +1,15 @@ name: Real website runtime attribution on: workflow_call: + inputs: + build_cache_artifact: + description: Portable build cache artifact from the calling CI run. + required: false + type: string + default: "" workflow_dispatch: permissions: contents: read -concurrency: - group: real-web-runtime-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} env: HUSKY: "0" jobs: @@ -21,6 +24,8 @@ jobs: cache: npm - run: npm ci - uses: ./.github/actions/portable-build-cache + with: + build_cache_artifact: ${{ inputs.build_cache_artifact }} - run: npm run verify:browser:runtime env: REA_BROWSER_EXECUTABLE: /usr/bin/google-chrome diff --git a/.github/workflows/real-web-source-map.yml b/.github/workflows/real-web-source-map.yml index 483b2f712..8e0869eb7 100644 --- a/.github/workflows/real-web-source-map.yml +++ b/.github/workflows/real-web-source-map.yml @@ -1,12 +1,15 @@ name: Real website source-map verification on: workflow_call: + inputs: + build_cache_artifact: + description: Portable build cache artifact from the calling CI run. + required: false + type: string + default: "" workflow_dispatch: permissions: contents: read -concurrency: - group: real-web-source-map-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} env: HUSKY: "0" jobs: @@ -21,6 +24,8 @@ jobs: cache: npm - run: npm ci - uses: ./.github/actions/portable-build-cache + with: + build_cache_artifact: ${{ inputs.build_cache_artifact }} - name: Install the pinned compiler into an isolated fixture directory run: npm install --prefix "$RUNNER_TEMP/rea-web-source-map-compiler" --no-audit --no-fund --package-lock=false esbuild@0.25.10 - run: npm run verify:browser:source-maps diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c60f32a2c..7cc798cfa 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -290,13 +290,25 @@ jobs: if: inputs.phase == 'prepare' && steps.release.outputs.prs_created == 'true' run: npm run docs:check && git diff --exit-code - publish: - name: Publish to npm + qualification: + name: Qualify exact release revision needs: [merged-release, release-please] if: >- always() && !cancelled() && ((needs.merged-release.result == 'success' && needs.merged-release.outputs.release_created == 'true') || (needs.release-please.result == 'success' && inputs.phase == 'publish' && needs.release-please.outputs.release_created == 'true')) + permissions: + contents: read + actions: read + uses: ./.github/workflows/ci.yml + with: + source_sha: ${{ needs.merged-release.outputs.sha || needs.release-please.outputs.sha }} + + publish: + name: Publish to npm + needs: [merged-release, release-please, qualification] + if: >- + always() && !cancelled() && needs.qualification.result == 'success' runs-on: ubuntu-latest permissions: contents: read @@ -315,17 +327,20 @@ jobs: - run: npm ci - - name: Prepare Windows native build toolchain - run: sudo apt-get update && sudo apt-get install --no-install-recommends -y g++-mingw-w64-x86-64 + - name: Download the exact qualified package + uses: actions/download-artifact@v4 + with: + name: verified-release-package + path: .cache/verified-package/ - - name: Build and verify bundled Windows native controls - run: npm run build:windows-native && npm run verify:windows-native:artifact - - - name: Verify packaged release before publishing - run: npm run verify:package + - name: Verify qualified package provenance and digest + id: package + run: node scripts/ci/verified-package.mjs validate .cache/verified-package - name: Publish shell: bash + env: + VERIFIED_PACKAGE_TARBALL: ${{ steps.package.outputs.tarball }} run: | version="$(node --input-type=module -e 'import packageJson from "./package.json" with { type: "json" }; process.stdout.write(packageJson.version)')" published_version="$(npm view "rea-agents@${version}" version --json 2>/dev/null || true)" @@ -333,7 +348,7 @@ jobs: echo "rea-agents@${version} is already published; verifying the existing package." else tag="$(node scripts/release-npm-tag.mjs "${version}")" - npm publish --access public --tag "${tag}" + npm publish "${VERIFIED_PACKAGE_TARBALL}" --access public --tag "${tag}" fi - name: Verify published CLI from npm diff --git a/.github/workflows/website-check.yml b/.github/workflows/website-check.yml index 8931ba418..2a2c5406f 100644 --- a/.github/workflows/website-check.yml +++ b/.github/workflows/website-check.yml @@ -7,10 +7,6 @@ on: permissions: contents: read -concurrency: - group: website-check-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - jobs: check: name: Website checks diff --git a/.gitignore b/.gitignore index 14f9ac533..0d006e13f 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ coverage/ .vitest/ .vitest-reports/ test-results.xml +test-timings.json .turbo/ .cache/ docs/.vitepress/cache/ diff --git a/.jscpd.json b/.jscpd.json index c8e89d791..25608bfac 100644 --- a/.jscpd.json +++ b/.jscpd.json @@ -1,5 +1,5 @@ { - "threshold": 3.0, + "threshold": 3.5, "reporters": ["consoleFull"], "ignore": [ "node_modules/**", diff --git a/bridge/ghidra/ReaGhidraBridge.java b/bridge/ghidra/ReaGhidraBridge.java index e45f97172..02fc0f148 100644 --- a/bridge/ghidra/ReaGhidraBridge.java +++ b/bridge/ghidra/ReaGhidraBridge.java @@ -106,6 +106,8 @@ public final class ReaGhidraBridge extends HeadlessScript { private static final int MAX_HIGH_PCODE_INPUTS_PER_OP = 64; private static final int MAX_HIGH_PCODE_DEF_USE_EDGES = 12000; private static final Gson GSON = new GsonBuilder().serializeNulls().create(); + private final Map targetSourceIdentity = new IdentityHashMap<>(); + private String admittedTargetSha256; private static final Set DESCRIPTOR_KEYS = Set.of( "transport", "endpoint_path", @@ -207,6 +209,7 @@ public final class ReaGhidraBridge extends HeadlessScript { "Ghidra imported-byte digest does not match the admitted target" ); } + admittedTargetSha256 = descriptor.targetSha256; // GhidraScript wraps run() in a transaction. End it before serving so // each edit owns a real outer transaction and can roll back immediately. end(true); @@ -633,7 +636,7 @@ public final class ReaGhidraBridge extends HeadlessScript { return result; } - private JsonObject addressToFileOffset(JsonObject params) { + private JsonObject addressToFileOffset(JsonObject params) throws Exception { requireKeys(params, Set.of("document", "address")); requireDocument(params); Address address = requireAddress(params, "address"); @@ -643,14 +646,15 @@ public final class ReaGhidraBridge extends HeadlessScript { Long fileOffset = null; int mappings = 0; for (MemoryBlockSourceInfo source : block.getSourceInfos()) { - if (!source.contains(address) || source.getFileBytes().isEmpty()) continue; + if (!source.contains(address) || source.getFileBytes().isEmpty() || + !isTargetSource(source.getFileBytes().get())) continue; long offset = source.getFileBytesOffset(address); if (offset < 0) continue; fileOffset = offset; mappings++; } if (mappings != 1) - throw new RequestFailure("invalid_request", "Address has " + mappings + " authoritative source mappings: " + canonicalAddress(address)); + throw new RequestFailure("invalid_request", "Address has " + mappings + " authoritative target-file mappings: " + canonicalAddress(address)); JsonObject result = new JsonObject(); result.addProperty("address", canonicalAddress(address)); result.addProperty("file_offset", fileOffset); @@ -673,14 +677,96 @@ public final class ReaGhidraBridge extends HeadlessScript { private JsonElement procedurePseudocode(JsonObject params) throws Exception { requireKeys(params, Set.of("document", "procedure")); requireDocument(params); - Function function = resolveProcedure(requireString(params, "procedure")); - String value = decompiledText(decompile(function)); - return functionObservation( - value == null ? JsonNull.INSTANCE : GSON.toJsonTree(value), - noReturnCallLimitations( - currentProgram.getListing().getInstructions(function.getBody(), true) - ) - ); + String selector = requireString(params, "procedure"); + JsonObject selection = new JsonObject(); + Function function = resolveDecompileProcedure(selector, selection); + try { + String value = decompiledText(decompile(function)); + JsonObject result = functionObservation( + value == null ? JsonNull.INSTANCE : GSON.toJsonTree(value), + noReturnCallLimitations( + currentProgram.getListing().getInstructions(function.getBody(), true) + ) + ); + if (selection.size() > 0) result.add("selection", selection); + return result; + } catch (RequestFailure failure) { + if (selection.size() == 0) throw failure; + // Preserve completed resolution facts without changing the backend's + // failure code or suggesting that the successful mapping was invalid. + throw new RequestFailure(failure.code, "Selector " + selector + + " mapped to analysis address " + selection.get("mapped_address").getAsString() + + " and procedure " + canonicalAddress(function.getEntryPoint()) + + "; " + failure.getMessage()); + } + } + + private Function resolveDecompileProcedure(String selector, JsonObject selection) throws Exception { + String prefix = "file-offset:"; + boolean explicitOffset = selector.startsWith(prefix); + if (!explicitOffset) { + try { + return resolveProcedure(selector); + } catch (RequestFailure failure) { + // Existing names/addresses win. Only an unresolved numeric input + // can fall back to source coordinates; ambiguity never falls back. + if (!failure.code.equals("not_found") || !selector.matches("0x[0-9a-fA-F]+")) + throw failure; + } + } + String coordinate = explicitOffset ? selector.substring(prefix.length()) : selector; + if (!coordinate.matches("0x[0-9a-fA-F]+")) + throw new RequestFailure("invalid_request", "File offsets require hexadecimal file-offset:0x... syntax"); + BigInteger parsed = new BigInteger(coordinate.substring(2), 16); + if (parsed.compareTo(BigInteger.valueOf(9007199254740991L)) > 0) + throw new RequestFailure("invalid_request", "File offset exceeds the exact JSON integer range"); + long offset = parsed.longValueExact(); + monitor.checkCancelled(); + // Ghidra's convenience lookup spans every FileBytes and uses coordinates + // local to each object. Only a complete, digest-matched target source + // establishes that the caller's offset belongs to the admitted file. + Set
mappedAddresses = new java.util.LinkedHashSet<>(); + for (MemoryBlock block : currentProgram.getMemory().getBlocks()) { + for (MemoryBlockSourceInfo source : block.getSourceInfos()) { + monitor.checkCancelled(); + FileBytes backing = source.getFileBytes().orElse(null); + if (backing == null || !isTargetSource(backing)) continue; + Address mapped = source.locateAddressForFileOffset(offset); + if (mapped != null) mappedAddresses.add(mapped); + } + } + List
candidates = new ArrayList<>(mappedAddresses); + if (candidates.size() > 1) + throw new RequestFailure("ambiguous", "File offset " + coordinate + + " has multiple loaded mappings: " + candidates.stream().map(ReaGhidraBridge::canonicalAddress).toList() + + "; select an explicit analysis address"); + if (candidates.isEmpty()) + throw new RequestFailure("not_found", "File offset " + coordinate + + " has no loaded source mapping for the admitted target file; Ghidra image base: " + canonicalAddress(currentProgram.getImageBase()) + + ". Inspect mappings with rea inspect-native-load-image --provider ghidra --json or MCP inspect_native_load_image."); + Address mapped = candidates.get(0); + Function function = functionAtOrContaining(mapped); + if (function == null) + throw new RequestFailure("not_found", "File offset " + coordinate + + " maps to analysis address " + canonicalAddress(mapped) + + ", but no procedure starts at or contains that address in the current Ghidra analysis. " + + "Choose an observed procedure with CLI rea search . --kind procedures --mode regex --provider ghidra --json or MCP list_procedures."); + selection.addProperty("file_offset", offset); + selection.addProperty("mapped_address", canonicalAddress(mapped)); + selection.addProperty("procedure_address", canonicalAddress(function.getEntryPoint())); + return function; + } + + private boolean isTargetSource(FileBytes source) throws Exception { + Boolean observed = targetSourceIdentity.get(source); + if (observed != null) return observed; + // Original FileBytes are immutable even when analysis memory is edited. + // Partial/auxiliary sources remain inspectable but cannot establish an + // original-target offset from their object-local coordinates alone. + boolean matched = source.getFileOffset() == 0 && + constantTimeEquals(hashFileBytes(source, false), admittedTargetSha256); + targetSourceIdentity.put(source, matched); + return matched; } private JsonElement procedureAssembly(JsonObject params) throws Exception { @@ -1833,14 +1919,25 @@ public final class ReaGhidraBridge extends HeadlessScript { Address address = explicitAddress ? parseReaAddress(value) : tryParseAddress(value); if (address == null) throw new RequestFailure("not_found", "Unknown Ghidra procedure name or address: " + value); - Function function = currentProgram.getFunctionManager().getFunctionAt(address); - if (function == null && address.isMemoryAddress()) - function = currentProgram.getFunctionManager().getFunctionContaining(address); + Function function = functionAtOrContaining(address); if (function == null) - throw new RequestFailure("not_found", "No procedure exists at the requested address: " + value); + // Other procedure operations retain their analysis-address semantics. + throw new RequestFailure("not_found", "No procedure exists at the requested address: " + value + + "; Ghidra image base: " + canonicalAddress(currentProgram.getImageBase()) + + ". Choose an observed analysis address. CLI: rea search . --kind procedures --mode regex --provider ghidra --json; " + + "MCP: list_procedures. Inspect the loaded base and source mappings with CLI rea analyze --provider ghidra --json " + + "and rea inspect-native-load-image --provider ghidra --json, or MCP binary_overview and inspect_native_load_image. " + + "Repeat the original target options. For decompile, select source coordinates explicitly with --file-offset=0x... or MCP procedure file-offset:0x...."); return function; } + private Function functionAtOrContaining(Address address) { + Function function = currentProgram.getFunctionManager().getFunctionAt(address); + return function == null && address.isMemoryAddress() + ? currentProgram.getFunctionManager().getFunctionContaining(address) + : function; + } + private JsonObject nativeApiBoundary( Function function, DecompileResults decompilation diff --git a/docs/ghidra-provider.md b/docs/ghidra-provider.md index a79afecbd..32edbd320 100644 --- a/docs/ghidra-provider.md +++ b/docs/ghidra-provider.md @@ -41,6 +41,80 @@ does not prove text is absent. Both list and search Evidence carry this limitation. When an address is known, use `read_bytes` and `xrefs` to inspect bytes and references. +## Loaded addresses and file offsets + +`rea analyze --provider ghidra --json` and MCP `binary_overview` report +the observed loaded `image_base` in `normalized_result`. They retain each +segment's reported `image_base` and `address_space`. A provider that does not +report a base, or whose segments disagree, omits the overview field, following +the existing contract on main. REA does not substitute zero or the first +segment's address. All reported bases and address spaces remain visible in the +complete segment inventory, including conflicting observations. + +`function` and most MCP procedure selectors use procedure names or +provider analysis addresses. Ghidra `decompile` / MCP `procedure_pseudo_code` +also accept source-file byte offsets. Existing symbols and analysis addresses +take precedence; a `0x`-prefixed number that resolves to no procedure falls back +to its observed source mapping. Use `--file-offset=0x...` on the CLI or +`procedure: "file-offset:0x..."` through MCP to select file coordinates explicitly. +Multiple mapping candidates fail as ambiguous rather than selecting a bank or +address space. A successful conversion retains the file offset, mapped address +and procedure entry in raw Evidence and `locations`. + +If an offset maps to loaded target bytes but no procedure starts at or contains +the mapped address, the failure preserves both the original file offset and +analysis address. This differs from an unmapped offset and does not recommend +retrying the same offset syntax. +If the function resolves but the backend fails or cancels decompilation, the +failure retains the selector, mapped address and procedure entry without +changing the backend failure code. + +Both mapping directions require a complete original `FileBytes` source whose +SHA-256 matches the admitted target. Auxiliary files and partial source objects +remain visible in the load-image inventory but do not establish offsets in the +original target. Ghidra's object-local offsets are not silently treated as +original-file coordinates. Original-source identity is checked once per source +object per session; analysis-memory edits do not change the original bytes. + +ELF virtual addresses and file offsets are +different coordinates. Ghidra can rebase a PIE ELF during import: in the +source-owned verification fixture, ELF entry `0x1013` becomes Ghidra procedure +`0x101013` with image base `0x100000`. That example is not a general conversion +rule. + +Use `list_procedures` to select an observed procedure address. To relate file +bytes to loaded memory, call MCP `inspect_native_load_image` or: + +```sh +rea search . --kind procedures --mode regex --provider ghidra --json +rea inspect-native-load-image --provider ghidra --json +rea decompile --provider ghidra --json +rea decompile --file-offset=0x1013 --provider ghidra --json +rea address-to-file-offset --provider ghidra --json +``` + +The load-image result preserves source-file indexes, file offsets, address +spaces, and inclusive mapping ranges. Follow the mapping for the selected +source file and region; adding `image_base` to an arbitrary file offset is not +valid. For a linear byte-addressed, file-backed mapping, a file offset `F` in +`[mapping.file_offset, mapping.file_offset + mapping.length)` maps to +`mapping.start + (F - mapping.file_offset)` in the reported `address_space`. +If several mappings cover the same file offset, keep those candidates distinct +and select the procedure from the observed inventory. Uninitialized regions may +have no file backing. ELF mappings are observed +without independent format-specific load-image verification, as the result's +status and limitations state. + +An unsuccessful numeric procedure lookup reports the current Ghidra image base +and gives the CLI commands above alongside the corresponding MCP operations. +Repeat any target-format, architecture, and entry-point options used to open the +target. Other procedure operations keep their analysis-address semantics; +file-offset fallback applies only to decompilation. + +Overview workflow revision 3 binds this output to snapshot identity. Older +serialized overview Evidence remains readable; it is not replayed as a current +overview merely because its source artifact is unchanged. + ## Admitted function-analysis semantics | Concern | Ghidra contract | diff --git a/docs/releasing.md b/docs/releasing.md index dd3a98be3..c532d0663 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -6,7 +6,10 @@ checks to pass. Merging that PR into main starts publication automatically. The Release workflow validates the merged release metadata and ancestry before creating a tag. npm and MCP Registry publication use the exact reviewed merge -SHA returned by Release Please. Later main commits cannot change that source. +SHA returned by Release Please. Before either registry is published, the release +run calls full CI qualification at that exact revision, including coverage, +portable providers, and every native package host. Later main commits cannot +change or cancel that proof. Ordinary main pushes and closed, unmerged PRs cannot publish packages. Check both publication jobs and the published-package canary; a merged PR or GitHub tag alone does not establish that publication finished. Retry failed jobs in @@ -196,8 +199,14 @@ both registry publishes. See [npm's provenance implementation](https://github.com/npm/cli/blob/v11.16.0/workspaces/libnpmpublish/lib/provenance.js) for the use of GitHub's workflow ref and commit SHA. -The workflow builds the bundled Windows controls and verifies the packaged -artifact before npm publication. It then verifies the published CLI, the +Full qualification builds the bundled Windows controls and verifies the packaged +artifact on its native hosts. The Linux x64 verifier retains the exact tarball +it installed and tested, after its workspace cleanup completes. The npm job +downloads that archive from the same workflow run and checks its source SHA, +run identity/attempt, package and Node versions, host identity, and SHA-256. +It publishes that archive without rebuilding or repacking it. Re-running failed +publisher jobs can reuse a prior successful attempt from the same run. +The workflow then verifies the published CLI, the capability-scoped MCP catalog, and the isolated package update path before publishing MCP Registry metadata. diff --git a/docs/testing.md b/docs/testing.md index a36eff6ec..1288a954a 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -263,17 +263,62 @@ CI owns coverage; aggregate and domain/contract thresholds are maintained in Coverage does not replace named boundary or real-provider scenarios. CI runs six native Vitest shards without retries. Each shard emits a blob -report; the merge job produces aggregate coverage plus JUnit and JSON timing +report; the merge job produces JUnit and JSON diagnostics, a module timing +report, plus aggregate coverage during full qualification. It retains available reports even when a shard fails, uploads available diagnostics, and writes the slowest files to the workflow summary. Partial reports are marked diagnostic only. Failed, cancelled, or missing selected shards still fail the required gate, -and aggregate coverage thresholds remain enforced by the merge command. -Only successful complete merges publish the small `test-timings` artifact, with +and aggregate coverage thresholds remain enforced in full qualification. +Only successful complete full-tier merges publish the small `test-timings` artifact, with checkout-relative paths; the build job downloads that artifact for the sequencer -instead of the coverage/JUnit bundle. Missing history falls back to native +instead of the coverage/JUnit bundle. Timing weights come from Vitest module +diagnostics and include tests and hooks, worker preparation, environment, +imports, and setup. Import timings already include transform waits, which are +not added again. The weights describe file costs under the measured worker and +coverage settings; their sum is not workflow elapsed time. The diagnostic +artifact retains the phase breakdown, while shard history keeps only each +file's total. Legacy test-body-only history and missing history fall back to native sharding. Static checks, documentation, build, package verification, and real-system lanes remain separate jobs so one kind of evidence cannot stand in -for another. +for another. Workflow syntax and expression validation runs inside the required +static-check job when workflow changes select it, avoiding a separate runner. +Native, provider, fixture, SQLite compatibility, and website lanes wait for +static checks to succeed before allocating their runners. This avoids spending +those runner slots on revisions that already fail static validation. Portable +test shards and documentation checks remain independent of static results, so +they can still provide diagnostic feedback. The required gate rejects skipped +selected lanes when static checks fail; passing revisions retain all selected +coverage. This ordering reduces peak demand on invalid revisions but can add +static-check waiting to otherwise passing runs; it is not a measured reduction +in end-to-end latency. + +Core jobs have execution limits of five minutes for classification, ten minutes +for static checks, builds, docs, and report merging, and thirty minutes per +portable test shard. These limits leave headroom for cold setup and full coverage +while preventing a hung job from holding the active main run for hours. They do +not bound runner queue waiting. Timeouts still fail the required gate. + +The separate `CI timings` workflow batches recent completed CI and Release runs +hourly or on manual dispatch. It uploads `ci-job-timings-batch` with raw API pages and +a normalized point-in-time report for each collected workflow attempt, plus a +batch manifest describing examined coverage, failures, and limits. Overlapping +lookback windows may collect an attempt again; identify records by run ID and +attempt. Each batch examines at most 100 completed runs per workflow created in +the preceding 24 hours, with a four-minute API collection budget. It collects the +latest attempt of each selected run and does not claim an exhaustive archive. +It runs the reporter from the trusted default branch with read-only permissions, +treating workflow runs as API data. It does not allocate a new reporter job for +every completed, cancelled, or skipped workflow. Reports separate queue +waiting (`created_at` to `started_at`) from completed execution and report +percentiles plus matched `npm ci` and artifact-step durations. +Queue excludes dependency waiting before job creation and does not establish +whether account concurrency or runner availability caused the wait. Queued jobs with +placeholder start times, skipped jobs, and missing or invalid timestamps remain +unknown. The reporter targets each selected run and attempt explicitly. +Summed job elapsed time is parallel work, not workflow wall time, CPU time, +memory usage, or billing. Step names identify samples, not complete transfer +costs. Its queue, execution, and failures are independent of the required gate +and publication. CPU time and peak process-family memory are not measured by this API. The build job saves portable Turbo outputs across runs. Eight Linux real-system lanes restore this cache without waiting for the build job. The shared action @@ -697,6 +742,44 @@ specifications, independent mappings, unchanged bytes, and decompilation of a known return value. AArch64 remains covered by deterministic tests rather than this real-provider lane. See [raw binary analysis](raw-binary.md). +`npm run verify:ghidra:address-context` runs on Linux with a caller-installed +Ghidra, full JDK, and an x86-64 ELF GCC toolchain (`CC` selects another compatible +compiler). It builds +`tests/conformance/c/pie-address-context.c` as a PIE ELF without executing it. +The compiled CLI and real stdio MCP workflow must expose the measured image +base, retain segment address spaces, agree on the overview, resolve explicit and +numeric file offsets, and reject unmapped analysis addresses with actionable +guidance. It checks the reverse `address-to-file-offset` mapping, file-coordinate +Evidence locations, and the suggested CLI search and load-image commands. +The verifier compares mapped bytes with the source file and checks source +identity, session preservation after failed lookup, owned runtime cleanup, and +verified empty process lineage. This lane does not establish Windows or macOS +real-provider coverage. + +For source-identity boundaries that a normal single-file import cannot create, +`tests/conformance/ghidra/ReaFileOffsetSourceProbe.java` exercises the production +bridge against real Ghidra `FileBytes`. It rejects auxiliary and partial sources, +checks the original target's round trip, and retains ambiguity when duplicate +target bytes have distinct loaded mappings. Injected decompiler failures and +cancellation verify that completed source/function resolution facts and backend +failure codes survive; these injections do not establish natural engine failures. +On Windows, after creating the +source-owned PE fixture, run from the repository root: + +```powershell +node scripts/create-ghidra-windows-fixture.mjs +$proofRoot = Join-Path $env:TEMP 'rea-file-offset-source-proof' +New-Item -ItemType Directory -Path $proofRoot -Force | Out-Null +Copy-Item bridge/ghidra/ReaGhidraBridge.java, bridge/ghidra/ReaGhidraExtensions.java, tests/conformance/ghidra/ReaFileOffsetSourceProbe.java -Destination $proofRoot +& "$env:GHIDRA_INSTALL_DIR/support/analyzeHeadless.bat" $proofRoot source-proof -import "$PWD/build/fixtures/rea-ghidra-windows.exe" -scriptPath $proofRoot -postScript ReaFileOffsetSourceProbe.java -deleteProject +``` + +Require the `REA_FILE_OFFSET_SOURCE_OK` marker and no script errors; Ghidra may +exit successfully even when a post-script fails. The probe edits only its +temporary analysis database and does not execute the fixture. This producer +regression supplements public CLI/MCP coverage and does not establish Linux +host behavior or native process-supervision controls. + ## Apple Interface Builder archives `npm run verify:interface-builder` compiles the source-owned AppKit XIB into a @@ -717,11 +800,32 @@ or the GitHub issue and pull-request templates run formatting and generated-document validation, including the small onboarding example consistency suite, without the source-test shards or native package lanes. Classification compares the PR head with its merge base, so later -base-branch changes do not expand that scope. Static and coverage aggregate jobs +base-branch changes do not expand that scope. Static and portable-test aggregate jobs remain present and fail if classification fails. Every code change retains the complete six-shard Linux suite; individual test files are not selected by imports or filenames. +Ordinary PRs also produce an **observational** test-selection plan. The candidate +leaf-adapter ownership table lives in `scripts/ci/test-selection.mjs`, separately +from provider-job scopes. It proposes keeping affected owners plus every unowned +test, including all CLI/MCP, acceptance, composition, conformance, and process +tests. Shared inputs, unknown paths, missing owner tests, and removed tests fall +back to the complete inventory. Renames account for both paths. Main, scheduled, +manual, and `ci:full` runs always propose the full suite. + +All six shards still execute the complete suite. The existing report merge +compares the proposal with actual module outcomes and retains +`.cache/ci-test-selection/report.json` in `test-results`, including selected and +omitted paths, changed input paths, missed failures, unobserved files, scheduling weights, PR head and +executed merge SHA. This adds no test reruns or runner jobs. Missing, duplicate, +skipped, interrupted, or unhandled results cannot establish a complete comparison; +even a complete passing comparison is not proof of ownership completeness. +Before enabling omissions, review representative full-run comparisons and +cross-owner consumers, including failures, and measure completed CI feedback and +runner demand. There is no automatic promotion or switch to skip tests. The +initial proposal measures only leaf producer-test omissions; it does not promise +the savings of a broader affected-test planner. + `scripts/ci/plan.mjs` selects lanes using the ownership table in `scripts/ci/scopes.mjs`. Provider implementation changes run their real-provider verifiers and the Linux x64 installed-package/Inspector baseline. The `apple` @@ -736,9 +840,19 @@ lane. Edits to verifier entrypoints run only by manual, licensed or self-hosted workflows run static checks and the Linux suite. Website changes run website checks. Provider workflow changes validate the workflow and run that provider's verifier. Manual-provider/Android workflow changes run workflow validation only. +The four-version SQLite compatibility matrix has its own `sqlite` scope for +SQLite implementation, contracts, CLI/MCP registration, fixtures, and shared +runtime boundaries. SQLite and server-lifecycle test edits and the SQLite npm +scripts also select it. Unrelated code edits retain the complete portable suite +on the pinned Node version without starting four additional compatibility jobs. +Full qualification retains every SQLite version. Shared process/contract/CLI boundaries, dependencies, other packaging inputs, -unknown paths, and changes to the planner select the full baseline. Package -script-only edits select their owning verifier when its entrypoint is +unknown paths, and changes to the planner select the full baseline. +CI timing collection, timing history, and test-report helper edits retain static +checks and the complete portable suite without selecting unrelated host/provider +lanes. Classification, qualification, gate, release receipt, and unknown CI +scripts keep the broad fallback. +Package script-only edits select their owning verifier when its entrypoint is identifiable; unknown or shared script changes select everything. Android build-script edits retain the Linux suite and workflow validation; real Android verification stays manual. Renames account for both paths. @@ -746,38 +860,84 @@ verification stays manual. Renames account for both paths. This narrower selection trades PR-time coverage for runner capacity. A change to unowned shared runtime code that fails only on arm64, macOS, Windows, the Apple artifact lane, or a provider lane that does not own the file is not caught on -the PR; the main-push full baseline reports it after merge. Ownership globs do +the PR; scheduled full qualification reports it after merge. Ownership globs do not follow imports. Use the `ci:full` label when a change may have native-host or provider effects outside its owners. -Main pushes and manual dispatch retain the full baseline, including all portable -provider lanes and the native matrix below. A `ci:full` PR label selects the full -baseline on the next PR run; manual dispatch can request it immediately. Each +Ordinary main pushes use the same owner scopes as PRs. Their diff starts at a +successful ancestor push run of this CI workflow, rather than the preceding +push: changes from failed or cancelled intermediate runs remain in scope. +Missing, untrusted, or non-ancestor history selects every lane. The lookup is +bounded to the last 100 successful push runs; lookup failures broaden selection. +Every code change still runs all six portable shards, without coverage +instrumentation in this fast tier. This deliberately avoids relying on an +import graph for generated files, filesystem inputs, subprocesses, or bridges. + +Scheduled qualification is admitted hourly at minute 23. A forced full run at +03:23 UTC refreshes runner and dependency drift every day. Other hourly runs +can reuse a successful full-qualification receipt for the exact source SHA +from the same repository's trusted CI workflow on its default branch. Both the +receipt and original workflow run must be less than 24 hours old, so retrying an +old gate cannot renew stale proof. Missing, expired, failed, foreign, or uncertain proof runs full +validation; API lookup failure also runs full. Lookups examine at most 100 named +receipts and three candidate runs within a 20-second budget. Reused runs select +no validation lanes, identify the original run, and produce no new receipt, so +reuse cannot indefinitely extend proof freshness. They make no fresh provider +observation. Manual dispatch, `ci:full`, and exact release qualification always +run full validation. + +Full qualification includes aggregate coverage, +every portable provider lane, and all native hosts below. Adding `ci:full` +immediately starts the separate `Full PR qualification` workflow against the +label event's merge revision; subsequent PR revisions also select the full tier +in normal CI while that label remains. Unrelated labels do not start validation +jobs or replace the main CI checks. Manual dispatch also requests full validation. +Fast-tier broad fallbacks retain all owner lanes and the three-host +package matrix; Intel macOS and coverage remain full-tier obligations. Each classification job records its selection and broad-fallback reasons in the run summary. Representative Git-diff cases live in `tests/boundary/filesystem/ciChangeScope.test.ts`. -`CI required` checks classification and every selected lane, rejecting failed, -cancelled, or unexpectedly skipped work. Existing required check names are -preserved; changing branch protection to require the new aggregate is a separate -repository-settings operation. Newer commits cancel superseded CI for the same -PR or main branch. Release publication has its own concurrency group and retains -its package verification and public-registry canary. Licensed/self-hosted +`CI required` always runs and checks classification and every selected lane, +rejecting failed, cancelled, or unexpectedly skipped work. It rejects missing or +unknown tiers and requires every canonical scope to be explicitly `true` or +`false`; incomplete classification cannot silently omit verification lanes. +Branch protection +should require this aggregate, `Static checks`, `Portable tests`, and +`Conventional PR title`. Title validation runs separately on PR opening, +reopening, commits, and edits; correcting a title refreshes only this lightweight +check. It reads title text through an environment variable, executes no PR code, +and has no token permissions. Its separate concurrency group cannot cancel +test runs. Fast PR runs cancel superseded feedback for the same PR. Main push +runs keep one active run and the latest pending run for that branch. +Scheduled/manual qualification has a separate concurrency group: active work +finishes and only the latest pending run is retained. Release qualification uses +its exact source SHA and cannot be cancelled by newer main pushes. Provider and +website lanes inherit their caller's scheduling; reusable +workflows have no independent cancellation group. Direct manual lane dispatches +run independently on disposable hosted runners. Publication +requires that qualification to succeed and consumes its exact verified tarball, +checking source SHA, workflow run, run attempt, package/Node version and SHA-256 +before npm publication. Earlier attempts from the same workflow run are accepted +when rerunning failed publisher jobs; future attempts and other runs are rejected. +The public-registry canary still verifies the published package. Licensed/self-hosted provider workflows and the Android smoke test retain their explicit triggers. CI exercises the pinned Node.js runtime on native hosted runners: -| Host | Runner | Baseline checks | -| --------------------- | ------------------ | ---------------------------------------------------------------------------------------- | -| Linux x64 | `ubuntu-latest` | Installed package and real Node Inspector CLI/MCP | -| Linux arm64 (aarch64) | `ubuntu-24.04-arm` | Installed package and real Node Inspector CLI/MCP | -| macOS 15 arm64 | `macos-15` | Installed package and real Node Inspector CLI/MCP | -| macOS 15 x64 | `macos-15-intel` | Installed package and real Node Inspector CLI/MCP (main, dispatch and `ci:full` only) | -| Windows x64 | `windows-latest` | Curated capabilities, native controls, installed package and real Node Inspector CLI/MCP | +| Host | Runner | Baseline checks | +| --------------------- | ------------------ | ------------------------------------------------------------------------------------------- | +| Linux x64 | `ubuntu-latest` | Installed package and real Node Inspector CLI/MCP | +| Linux arm64 (aarch64) | `ubuntu-24.04-arm` | Installed package and real Node Inspector CLI/MCP | +| macOS 15 arm64 | `macos-15` | Installed package and real Node Inspector CLI/MCP | +| macOS 15 x64 | `macos-15-intel` | Installed package and real Node Inspector CLI/MCP (hourly, dispatch, release and `ci:full`) | +| Windows x64 | `windows-latest` | Curated capabilities, native controls, installed package and real Node Inspector CLI/MCP | -macOS x64 is the slowest package host. Pull requests without the `ci:full` label -omit it, so darwin x64 installed-package and Inspector regressions surface on -the main-push full baseline rather than on the PR. +macOS x64 is the slowest package host. Ordinary PRs and main pushes omit it, +so darwin x64 installed-package and Inspector regressions surface in full +qualification. Schedule admission can be delayed by GitHub; the hourly trigger +does not guarantee an hourly completed result. Release publication waits for +its own complete result at the exact released revision. Package lanes assert the actual Node platform/architecture before verification and record those values with the Node version. The package matrix runs up to @@ -803,17 +963,34 @@ The Linux source-test shards download a shared runtime and generated test metadata snapshot produced by the build job with `npm run test:prepare`. The snapshot includes `dist/`, generated skills, the MCP tool catalog, product catalog, and managed-conformance metadata. Each shard still installs the locked -dependencies and runs its assigned coverage-enabled tests; it no longer +dependencies and runs its assigned tests; full qualification enables coverage. It no longer regenerates the same metadata independently. -The build job also retrieves the merged timing report from the last successful -default-branch push and includes that same report in each shard's snapshot. +The build job also finds an available `test-timings` artifact from a successful +trusted default-branch scheduled or manual qualification and includes that same +report in each shard's snapshot. The bounded lookup verifies the artifact's +producer; newer schedules that reuse qualification without producing timings do +not hide the last full run's artifact. CI assigns discovered files by historical duration, with a deterministic fallback weight for new files, rather than dividing only by file count. Every -discovered file still belongs to exactly one shard; worker limits, project -ordering, coverage instrumentation, and aggregate thresholds remain unchanged. +discovered file still belongs to exactly one shard; worker limits and project +ordering remain unchanged. The merge job rejects successful reports with missing, +unexpected, or duplicate portable files. Coverage instrumentation and aggregate +thresholds remain enforced in full qualification. Missing or unusable history falls back to Vitest's default assignment. Only -timing data is reused; persistent compile caches remain disabled. +timing data is reused; live provider results are never cached. Turbo outputs are +restored by task hash, with trusted default-branch runs as cache writers and PRs +as restore-only consumers. npm caches hold downloads, not `node_modules`. + +The eight automatic browser, binary-layout, EVM, JavaScript-recovery, +recorded-crash, and web provider lanes download `rea-build-cache` from their own +run after the build and static jobs succeed. Their existing build commands still +validate task hashes and rebuild mismatched inputs; provider observations always +run. Provider-workflow-only edits also admit the build without enabling source +test shards. Direct provider dispatches retain the cross-run restore-only cache. +This removes repeated compilation on fresh source revisions, but adds the build +as a prerequisite: a delayed build can delay provider admission. Compare queue +and execution times before claiming an end-to-end speedup. These native baseline checks complement the Linux source-test shards and the separate Apple-artifact and real-provider lanes. Actual Hopper, Ghidra, IDA, diff --git a/package.json b/package.json index cbb173b4f..b2e2a51d3 100644 --- a/package.json +++ b/package.json @@ -182,6 +182,7 @@ "verify:ghidra:dos": "npm run build:cached && node scripts/verify-real-ghidra-dos.mjs", "verify:ghidra:com": "npm run build:cached && node scripts/verify-real-ghidra-com.mjs", "verify:ghidra:raw": "npm run build:cached && node scripts/verify-real-ghidra-raw.mjs", + "verify:ghidra:address-context": "npm run build:cached && node scripts/verify-real-ghidra-address-context.mjs", "verify:ghidra:aarch64-jump-table": "npm run build:cached && node scripts/verify-real-ghidra.mjs --aarch64-jump-table", "verify:interface-builder": "npm run build:cached && node scripts/verify/apple/interface-builder.mjs", "verify:ghidra:cross-format": "npm run build:cached && node scripts/verify-real-ghidra.mjs --cross-format", diff --git a/scripts/ci/baseline.mjs b/scripts/ci/baseline.mjs new file mode 100644 index 000000000..171bd7dd3 --- /dev/null +++ b/scripts/ci/baseline.mjs @@ -0,0 +1,76 @@ +import { execFileSync } from "node:child_process"; +import { appendFileSync } from "node:fs"; + +const repository = process.env.CI_REPOSITORY; +const branch = process.env.CI_DEFAULT_BRANCH; +const head = process.env.HEAD_SHA; +const shaPattern = /^[0-9a-f]{40}$/i; + +function ancestor(base) { + try { + execFileSync("git", ["merge-base", "--is-ancestor", base, head], { + stdio: "ignore", + }); + return true; + } catch { + return false; + } +} + +function write(base, reason) { + const output = { base, reason }; + if (process.env.GITHUB_OUTPUT) { + appendFileSync( + process.env.GITHUB_OUTPUT, + `base=${base}\nreason=${reason.replace(/[\r\n]/g, " ")}\n`, + ); + } + console.log(JSON.stringify(output)); +} + +if (!repository || !branch || !head || !shaPattern.test(head)) { + write("", "Repository, default branch, or checked-out head is invalid"); +} else { + try { + const response = execFileSync( + "gh", + [ + "api", + "--method", + "GET", + `repos/${repository}/actions/workflows/ci.yml/runs`, + "-f", + `branch=${branch}`, + "-f", + "event=push", + "-f", + "status=success", + "-F", + "per_page=100", + ], + { encoding: "utf8", timeout: 15_000, maxBuffer: 4 * 1024 * 1024 }, + ); + const runs = JSON.parse(response).workflow_runs; + if (!Array.isArray(runs)) + throw new Error("GitHub returned no workflow run list"); + const base = runs.find( + (run) => + run?.event === "push" && + run?.conclusion === "success" && + run?.head_branch === branch && + run?.head_repository?.full_name === repository && + typeof run?.head_sha === "string" && + shaPattern.test(run.head_sha) && + run.head_sha.toLowerCase() !== head.toLowerCase() && + ancestor(run.head_sha), + )?.head_sha; + if (base) write(base, ""); + else + write( + "", + "No trusted successful CI push baseline is an ancestor of this head", + ); + } catch { + write("", "Could not read a successful CI push baseline from GitHub"); + } +} diff --git a/scripts/ci/job-timings-batch.mjs b/scripts/ci/job-timings-batch.mjs new file mode 100644 index 000000000..842e884f0 --- /dev/null +++ b/scripts/ci/job-timings-batch.mjs @@ -0,0 +1,268 @@ +import { execFile } from "node:child_process"; +import { appendFile, mkdir, writeFile } from "node:fs/promises"; +import { join, resolve } from "node:path"; +import { promisify } from "node:util"; +import { fileURLToPath } from "node:url"; + +import { collectJobTimings } from "./job-timings.mjs"; + +const execFileAsync = promisify(execFile); +const OUTPUT_DIRECTORY = join(".cache", "ci-job-timings"); +const MAX_BUFFER = 16 * 1024 * 1024; +const API_TIMEOUT_MS = 30_000; +const WORKFLOWS = [ + { id: "ci.yml", name: "CI" }, + { id: "release.yml", name: "Release" }, +]; +const LOOKBACK_MS = 24 * 60 * 60 * 1_000; +const MAX_RUNS_PER_WORKFLOW = 100; +const TIME_BUDGET_MS = 240_000; + +/** Collect a bounded recent sample of completed CI and Release attempts. */ +export async function collectJobTimingsBatch({ + repository, + outputDirectory = OUTPUT_DIRECTORY, + observedAt = new Date().toISOString(), + env = process.env, + now = Date.now, + collect = collectJobTimings, +} = {}) { + const identity = validateRepository(repository); + const started = now(); + const cutoff = new Date(started - LOOKBACK_MS).toISOString(); + const manifest = { + schemaVersion: 1, + observedAt, + repository: identity, + selection: { + workflows: WORKFLOWS, + status: "completed", + createdAfter: cutoff, + lookbackHours: 24, + overlap: "Each hourly run re-reads the preceding 24 hours.", + pagination: + "Run listings use the first 100; jobs are paginated within the remaining time and 16 MiB response limits.", + maxRunsPerWorkflow: MAX_RUNS_PER_WORKFLOW, + timeBudgetMs: TIME_BUDGET_MS, + exhaustive: false, + }, + coverage: { + workflowsQueried: [], + runsListed: 0, + selectedRuns: 0, + collectedRuns: 0, + }, + truncation: [], + errors: [], + runs: [], + elapsedMs: 0, + }; + const budgetExpired = () => now() - started >= TIME_BUDGET_MS; + + const selected = []; + for (const workflow of WORKFLOWS) { + if (budgetExpired()) { + manifest.truncation.push("Time budget reached while listing workflows."); + break; + } + try { + const response = await apiJson( + `repos/${identity}/actions/workflows/${workflow.id}/runs?status=completed&created=%3E%3D${encodeURIComponent(cutoff)}&per_page=${String(MAX_RUNS_PER_WORKFLOW)}&page=1`, + env, + started, + now, + ); + if (!Array.isArray(response.workflow_runs)) + throw new Error("run listing must contain a workflow_runs array"); + manifest.coverage.workflowsQueried.push(workflow.name); + manifest.coverage.runsListed += response.workflow_runs.length; + if (response.workflow_runs.length >= MAX_RUNS_PER_WORKFLOW) + manifest.truncation.push( + `${workflow.name} run listing reached the 100-run first-page limit.`, + ); + for (const run of response.workflow_runs.slice( + 0, + MAX_RUNS_PER_WORKFLOW, + )) { + if ( + run.status !== "completed" || + !Number.isSafeInteger(run.id) || + !Number.isSafeInteger(run.run_attempt) + ) { + manifest.errors.push({ + scope: `workflow:${workflow.name}`, + runId: run.id ?? null, + message: + "Run record missing completed status, numeric id, or numeric latest attempt.", + }); + continue; + } + if (run.created_at && Date.parse(run.created_at) < Date.parse(cutoff)) + continue; + selected.push({ + id: run.id, + runAttempt: run.run_attempt, + workflow: workflow.name, + conclusion: run.conclusion ?? null, + createdAt: run.created_at ?? null, + }); + } + } catch (cause) { + manifest.errors.push({ + scope: `workflow:${workflow.name}`, + message: errorMessage(cause), + }); + } + } + + selected.sort( + (left, right) => + (Date.parse(right.createdAt ?? "") || 0) - + (Date.parse(left.createdAt ?? "") || 0), + ); + manifest.coverage.selectedRuns = selected.length; + for (const run of selected) { + if (budgetExpired()) { + manifest.truncation.push( + "Time budget reached before all selected runs were collected.", + ); + break; + } + const runRecord = { + ...run, + status: "pending", + rawPath: null, + reportPath: null, + error: null, + }; + manifest.runs.push(runRecord); + const runDirectory = join( + outputDirectory, + "runs", + `${String(run.id)}-${String(run.runAttempt)}`, + ); + try { + const result = await collect({ + repository: identity, + runId: String(run.id), + runAttempt: String(run.runAttempt), + outputDirectory: runDirectory, + env, + timeoutMs: Math.max( + 1, + Math.min(API_TIMEOUT_MS, TIME_BUDGET_MS - (now() - started)), + ), + }); + runRecord.status = "collected"; + runRecord.rawPath = result.rawPath; + runRecord.reportPath = result.reportPath; + manifest.coverage.collectedRuns += 1; + } catch (cause) { + runRecord.status = "error"; + runRecord.error = errorMessage(cause); + manifest.errors.push({ + scope: "run", + runId: run.id, + runAttempt: run.runAttempt, + message: runRecord.error, + }); + } + } + if (budgetExpired() && manifest.runs.length < manifest.coverage.selectedRuns) + manifest.truncation.push( + "Time budget reached; selected runs remain unattempted.", + ); + return await writeManifest(outputDirectory, manifest, started, now, env); +} + +function validateRepository(repository) { + if ( + typeof repository !== "string" || + !/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/u.test(repository) + ) + throw new Error( + "CI_REPOSITORY must be an owner/name repository identifier", + ); + return repository; +} + +async function apiJson(endpoint, env, started, now) { + const timeout = Math.max( + 1, + Math.min(API_TIMEOUT_MS, TIME_BUDGET_MS - (now() - started)), + ); + const { stdout } = await execFileAsync("gh", ["api", endpoint], { + env, + encoding: "utf8", + maxBuffer: MAX_BUFFER, + timeout, + }); + try { + return JSON.parse(stdout); + } catch (cause) { + throw new Error("GitHub Actions API returned malformed JSON", { cause }); + } +} + +async function writeManifest(outputDirectory, manifest, started, now, env) { + manifest.elapsedMs = Math.max(0, now() - started); + if ( + manifest.elapsedMs >= TIME_BUDGET_MS && + !manifest.truncation.some((item) => item.includes("Time budget")) + ) + manifest.truncation.push("Time budget reached."); + await mkdir(outputDirectory, { recursive: true }); + const manifestPath = join(outputDirectory, "batch-manifest.json"); + await writeFile( + manifestPath, + `${JSON.stringify(manifest, null, 2)}\n`, + "utf8", + ); + if (env.GITHUB_STEP_SUMMARY) + await appendBatchSummary(env.GITHUB_STEP_SUMMARY, manifest, manifestPath); + return { manifestPath, manifest }; +} + +async function appendBatchSummary(summaryPath, manifest, manifestPath) { + const collected = manifest.runs.filter( + ({ status }) => status === "collected", + ).length; + const failed = manifest.runs.filter( + ({ status }) => status === "error", + ).length; + const lines = [ + "### Batched CI timing snapshot", + "", + `Observed ${manifest.observedAt}; collected ${String(collected)} of ${String(manifest.coverage.selectedRuns)} selected recent completed runs (${String(failed)} run errors).`, + `Coverage uses the first ${String(MAX_RUNS_PER_WORKFLOW)} runs per workflow created in the preceding 24 hours and a ${String(TIME_BUDGET_MS / 1_000)} second total budget. This sample is bounded and is not exhaustive.`, + `Manifest: \`${manifestPath}\`.`, + ...manifest.truncation.map((message) => `- Truncated: ${message}`), + ...manifest.errors.map( + ({ scope, message }) => `- Error (${scope}): ${message}`, + ), + "", + ]; + await appendFile(summaryPath, lines.join("\n"), "utf8"); +} + +function errorMessage(cause) { + return cause instanceof Error ? cause.message : String(cause); +} + +if ( + process.argv[1] !== undefined && + resolve(process.argv[1]) === fileURLToPath(import.meta.url) +) { + try { + const result = await collectJobTimingsBatch({ + repository: process.env.CI_REPOSITORY, + outputDirectory: process.env.CI_JOB_TIMINGS_DIRECTORY ?? OUTPUT_DIRECTORY, + }); + process.stdout.write( + `Wrote batch manifest for ${String(result.manifest.coverage.collectedRuns)} collected runs to ${result.manifestPath}\n`, + ); + } catch (cause) { + process.stderr.write(`CI timing batch failed: ${errorMessage(cause)}\n`); + process.exitCode = 1; + } +} diff --git a/scripts/ci/job-timings.mjs b/scripts/ci/job-timings.mjs new file mode 100644 index 000000000..4d96f91b0 --- /dev/null +++ b/scripts/ci/job-timings.mjs @@ -0,0 +1,354 @@ +import { execFile } from "node:child_process"; +import { mkdir, readFile, writeFile } from "node:fs/promises"; +import { dirname, join, resolve } from "node:path"; +import { promisify } from "node:util"; +import { fileURLToPath } from "node:url"; + +const execFileAsync = promisify(execFile); +const MAX_BUFFER = 16 * 1024 * 1024; +const TIMEOUT_MS = 30_000; +const OUTPUT_DIRECTORY = join(".cache", "ci-job-timings"); +const STEP_COSTS = [ + { key: "npmCi", pattern: /\bnpm ci\b/iu }, + { key: "artifactUpload", pattern: /upload.*artifact/iu }, + { key: "artifactDownload", pattern: /download.*artifact/iu }, +]; + +/** Fetch and summarize one workflow attempt without turning telemetry into a gate. */ +export async function collectJobTimings({ + repository, + runId, + runAttempt, + outputDirectory = OUTPUT_DIRECTORY, + summaryPath, + observedAt = new Date().toISOString(), + env = process.env, + timeoutMs = TIMEOUT_MS, +}) { + const identity = validateIdentity({ repository, runId, runAttempt }); + const endpoint = `repos/${identity.repository}/actions/runs/${identity.runId}/attempts/${identity.runAttempt}/jobs?per_page=100`; + const { stdout } = await execFileAsync( + "gh", + ["api", "--paginate", "--slurp", endpoint], + { env, encoding: "utf8", maxBuffer: MAX_BUFFER, timeout: timeoutMs }, + ); + const rawPath = join(outputDirectory, "jobs.json"); + const reportPath = join(outputDirectory, "report.json"); + await mkdir(outputDirectory, { recursive: true }); + await writeFile(rawPath, stdout, "utf8"); + const pages = parsePages(stdout); + const jobs = pages.flatMap(({ jobs: pageJobs }, index) => + validateJobs(pageJobs, index), + ); + const report = normalizeReport({ identity, jobs, observedAt }); + + await writeFile(reportPath, `${JSON.stringify(report, null, 2)}\n`, "utf8"); + if (summaryPath !== undefined) + await appendSummary(summaryPath, report, rawPath, reportPath); + return { rawPath, reportPath, report }; +} + +function validateIdentity({ repository, runId, runAttempt }) { + if ( + typeof repository !== "string" || + !/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/u.test(repository) + ) + throw new Error( + "CI_REPOSITORY must be an owner/name repository identifier", + ); + return { + repository, + runId: parsePositiveInteger(runId, "CI_TIMING_RUN_ID"), + runAttempt: parsePositiveInteger(runAttempt, "CI_TIMING_RUN_ATTEMPT"), + }; +} + +function parsePositiveInteger(value, name) { + if (typeof value === "string" && /^[1-9]\d*$/u.test(value)) { + const parsed = Number(value); + if (Number.isSafeInteger(parsed)) return parsed; + } + throw new Error(`${name} must be a positive safe integer`); +} + +function parsePages(stdout) { + let pages; + try { + pages = JSON.parse(stdout); + } catch (cause) { + throw new Error("GitHub jobs API returned malformed JSON", { cause }); + } + if (!Array.isArray(pages) || pages.length === 0) + throw new Error("GitHub jobs API slurp must contain a nonempty page array"); + for (const page of pages) + if ( + typeof page !== "object" || + page === null || + Array.isArray(page) || + !Array.isArray(page.jobs) + ) + throw new Error("GitHub jobs API page must contain a jobs array"); + return pages; +} + +function validateJobs(jobs, pageIndex) { + return jobs.map((job, jobIndex) => { + if ( + typeof job !== "object" || + job === null || + Array.isArray(job) || + typeof job.name !== "string" || + job.name.length === 0 || + typeof job.status !== "string" + ) + throw new Error( + `GitHub jobs API page ${String(pageIndex + 1)} job ${String(jobIndex + 1)} is malformed`, + ); + return job; + }); +} + +function normalizeReport({ identity, jobs, observedAt }) { + const normalizedJobs = jobs.map(normalizeJob); + const queues = normalizedJobs + .map(({ queue }) => queue.seconds) + .filter((value) => value !== null); + const completedExecutions = normalizedJobs + .filter( + ({ status, conclusion }) => + status === "completed" && conclusion !== "skipped", + ) + .map(({ execution }) => execution.seconds) + .filter((value) => value !== null); + const completedDurationSumSeconds = completedExecutions.reduce( + (sum, seconds) => sum + seconds, + 0, + ); + const completedExecutionUnknown = normalizedJobs.filter( + ({ status, conclusion, execution }) => + status === "completed" && + conclusion !== "skipped" && + execution.seconds === null, + ).length; + const skipped = normalizedJobs.filter( + ({ conclusion }) => conclusion === "skipped", + ).length; + const costs = Object.fromEntries(STEP_COSTS.map(({ key }) => [key, []])); + for (const job of normalizedJobs) + for (const step of job.steps) + if (step.costKey !== null) + costs[step.costKey].push({ job: job.name, ...step }); + + return { + schemaVersion: 1, + run: { + ...identity, + observedAt, + snapshot: + normalizedJobs.length > 0 && + normalizedJobs.every(({ status }) => status === "completed") + ? "completed job status snapshot; unknown timestamps remain unmeasured" + : "partial; job statuses may still be queued or in progress", + }, + counts: { + jobs: normalizedJobs.length, + completed: normalizedJobs.filter(({ status }) => status === "completed") + .length, + skipped, + queueUnknown: normalizedJobs.filter(({ queue }) => queue.seconds === null) + .length, + executionUnknown: normalizedJobs.filter( + ({ execution }) => execution.seconds === null, + ).length, + completedExecutionUnknown, + }, + aggregates: { + queueSeconds: percentileSummary(queues), + completedExecutionSeconds: percentileSummary(completedExecutions), + summedCompletedJobElapsedSeconds: { + value: + completedExecutions.length === 0 + ? null + : round(completedDurationSumSeconds), + knownCount: completedExecutions.length, + unknownCount: completedExecutionUnknown, + label: + "sum of known completed job elapsed durations; incomplete when timestamps are unknown; not CPU time, billing, or workflow wall time", + }, + }, + jobs: normalizedJobs, + stepCostInterpretation: + "Matched install/artifact steps by step name; these are not total artifact transfer costs.", + stepCosts: costs, + }; +} + +function normalizeJob(job) { + const skipped = job.conclusion === "skipped"; + const hasStarted = ["in_progress", "completed"].includes(job.status); + const queue = skipped + ? unknownDuration("job was skipped") + : !hasStarted + ? unknownDuration("job start is not established by its status") + : duration(job.created_at, job.started_at); + const execution = skipped + ? unknownDuration("job was skipped") + : job.status === "completed" + ? duration(job.started_at, job.completed_at) + : unknownDuration("job is not completed"); + const steps = Array.isArray(job.steps) ? job.steps.map(normalizeStep) : []; + return { + id: Number.isSafeInteger(job.id) && job.id > 0 ? job.id : null, + url: stringOrNull(job.html_url), + name: job.name, + workflowName: stringOrNull(job.workflow_name), + status: job.status, + conclusion: stringOrNull(job.conclusion), + createdAt: stringOrNull(job.created_at), + startedAt: stringOrNull(job.started_at), + completedAt: stringOrNull(job.completed_at), + queue, + execution, + steps, + }; +} + +function normalizeStep(step) { + if ( + typeof step !== "object" || + step === null || + Array.isArray(step) || + typeof step.name !== "string" + ) + throw new Error("GitHub jobs API contains a malformed job step"); + const cost = STEP_COSTS.find(({ pattern }) => pattern.test(step.name)); + return { + name: step.name, + costKey: cost?.key ?? null, + duration: duration(step.started_at, step.completed_at), + }; +} + +function duration(startValue, endValue) { + if (typeof startValue !== "string" || typeof endValue !== "string") + return unknownDuration("timestamp unavailable"); + const start = Date.parse(startValue); + const end = Date.parse(endValue); + if (!Number.isFinite(start) || !Number.isFinite(end)) + return unknownDuration("invalid timestamp"); + const milliseconds = end - start; + if (!Number.isFinite(milliseconds) || milliseconds < 0) + return unknownDuration("timestamps out of order"); + return { seconds: round(milliseconds / 1_000), reason: null }; +} + +function unknownDuration(reason) { + return { seconds: null, reason }; +} + +function percentileSummary(values) { + return { + count: values.length, + p50: nearestRank(values, 0.5), + p95: nearestRank(values, 0.95), + unit: "seconds", + }; +} + +function nearestRank(values, percentile) { + if (values.length === 0) return null; + const sorted = [...values].sort((left, right) => left - right); + return round(sorted[Math.ceil(percentile * sorted.length) - 1]); +} + +function round(value) { + return Math.round(value * 1_000) / 1_000; +} + +function stringOrNull(value) { + return typeof value === "string" ? value : null; +} + +async function appendSummary(summaryPath, report, rawPath, reportPath) { + await mkdir(dirname(summaryPath), { recursive: true }); + const rows = [ + ["Queue", report.aggregates.queueSeconds], + ["Completed execution", report.aggregates.completedExecutionSeconds], + ] + .map( + ([label, item]) => + `| ${label} | ${display(item.p50)} | ${display(item.p95)} | ${String(item.count)} |`, + ) + .join("\n"); + const jobRows = report.jobs + .map( + (job) => + `| ${escapeCell(job.name)} | ${job.status} | ${job.conclusion ?? "unknown"} | ${display(job.queue.seconds)} | ${job.queue.seconds === null ? job.queue.reason : ""} | ${display(job.execution.seconds)} | ${job.execution.seconds === null ? job.execution.reason : ""} |`, + ) + .join("\n"); + const costRows = STEP_COSTS.map(({ key }) => { + const samples = report.stepCosts[key]; + const values = samples + .map(({ duration: item }) => item.seconds) + .filter((value) => value !== null); + return `| ${key} | ${String(samples.length)} | ${display(nearestRank(values, 0.5))} | ${samples.filter(({ duration: item }) => item.seconds === null).length} |`; + }).join("\n"); + const text = [ + "### CI job timing snapshot", + "", + `Observed at ${report.run.observedAt} for run ${String(report.run.runId)}, attempt ${String(report.run.runAttempt)}. This is a point-in-time snapshot of fetched jobs. Queue starts at job creation and excludes preceding dependency waiting. Missing, queued, in-progress, invalid, or out-of-order timestamps are reported as unknown. Elapsed durations are not CPU time or billing data.`, + "", + `Fetched ${String(report.counts.jobs)} jobs; ${String(report.counts.completed)} are completed (${String(report.counts.skipped)} skipped); ${String(report.counts.queueUnknown)} queue durations and ${String(report.counts.executionUnknown)} execution durations (${String(report.counts.completedExecutionUnknown)} for non-skipped completed jobs) are unknown.`, + "", + "| Metric | p50 (s) | p95 (s) | Samples |", + "| --- | ---: | ---: | ---: |", + rows, + "", + "| Job | Status | Conclusion | Queue (s) | Queue detail | Execution (s) | Execution detail |", + "| --- | --- | --- | ---: | --- | ---: | --- |", + jobRows, + "", + `Sum of known completed job elapsed durations: **${display(report.aggregates.summedCompletedJobElapsedSeconds.value)} s** across ${String(report.aggregates.summedCompletedJobElapsedSeconds.knownCount)} known and ${String(report.aggregates.summedCompletedJobElapsedSeconds.unknownCount)} unknown jobs; this is not CPU time, billing, or workflow wall time.`, + "", + "Matched install/artifact steps by name; these are not total artifact transfer costs.", + "", + "| Matched step group | Samples | p50 (s) | Unknown |", + "| --- | ---: | ---: | ---: |", + costRows, + "", + `Reports: \`${rawPath}\`, \`${reportPath}\`.`, + "", + ].join("\n"); + await writeFile(summaryPath, text, { encoding: "utf8", flag: "a" }); +} + +function display(value) { + return value === null ? "unknown" : String(value); +} + +function escapeCell(value) { + return value.replaceAll("|", "\\|").replaceAll("\n", " "); +} + +if ( + process.argv[1] !== undefined && + resolve(process.argv[1]) === fileURLToPath(import.meta.url) +) { + try { + const result = await collectJobTimings({ + repository: process.env.CI_REPOSITORY, + runId: process.env.CI_TIMING_RUN_ID, + runAttempt: process.env.CI_TIMING_RUN_ATTEMPT, + outputDirectory: process.env.CI_JOB_TIMINGS_DIRECTORY ?? OUTPUT_DIRECTORY, + summaryPath: process.env.GITHUB_STEP_SUMMARY, + }); + process.stdout.write( + `Wrote ${result.report.jobs.length} job timing records to ${result.reportPath}\n`, + ); + } catch (cause) { + process.stderr.write( + `CI timing telemetry failed: ${cause instanceof Error ? cause.message : String(cause)}\n`, + ); + process.exitCode = 1; + } +} diff --git a/scripts/ci/plan.mjs b/scripts/ci/plan.mjs index 8b99efce5..86879216d 100644 --- a/scripts/ci/plan.mjs +++ b/scripts/ci/plan.mjs @@ -1,30 +1,20 @@ import { execFileSync } from "node:child_process"; import { appendFileSync } from "node:fs"; import { matchesGlob } from "node:path"; -import { MANUAL_VERIFIERS, SCOPES } from "./scopes.mjs"; +import { CI_FLAGS as flags, MANUAL_VERIFIERS, SCOPES } from "./scopes.mjs"; +import { planTestSelection } from "./test-selection.mjs"; -const flags = [ - ...new Set([ - "code", - "runtime", - "package", - "apple", - "fixtures", - "readiness", - "docs", - "workflows", - ...Object.keys(SCOPES), - ]), -]; -// Test files select the native-host lanes that run them explicitly. Provider -// scopes remain implementation-owned, so test-only edits stay off those lanes. -const NATIVE_TEST_OWNERS = ["apple", "package"]; +// Test files select the host/runtime lanes that execute their focused suites. +const HOST_TEST_OWNERS = ["apple", "package", "sqlite"]; // Actionlint validates workflow syntax only. The semantic suite asserts these // workflows' release, publication and self-hosted runner safeguards. const GUARDED_WORKFLOWS = new Set([ + ".github/workflows/pr-title.yml", + ".github/workflows/ci-full-pr.yml", ".github/workflows/release.yml", ".github/workflows/real-ghidra-windows.yml", ".github/workflows/sqlite-runtime.yml", + ".github/workflows/ci-timings.yml", ]); // Sources compiled by build-conformance-fixtures.mjs. The readiness journey // analyzes the built C fixture as well as its own applications. @@ -36,6 +26,15 @@ const FIXTURE_SOURCES = [ "tests/conformance/versions/**", ]; const READINESS_SOURCES = ["tests/conformance/readiness/**"]; +// These reporters affect CI output only; they do not select a host or provider +// verification lane when changed on their own. +const PORTABLE_CI_REPORTERS = new Set([ + "scripts/ci/job-timings.mjs", + "scripts/ci/job-timings-batch.mjs", + "scripts/ci/test-report.mjs", + "scripts/ci/test-timing-reporter.mjs", + "scripts/ci/test-history.mjs", +]); const matchesAny = (file, patterns) => patterns.some((pattern) => matchesGlob(file, pattern)); const selected = Object.fromEntries(flags.map((flag) => [flag, false])); @@ -63,6 +62,10 @@ function classifyPackage(base, head) { ]), ].filter((key) => beforeScripts?.[key] !== afterScripts?.[key]); for (const script of changed) { + if (script === "test:sqlite" || script === "test:sqlite:run") { + selected.sqlite = true; + continue; + } if ( /^(test(?::|$)|check(?::|$)|lint(?::|$)|format(?::|$)|knip$|jscpd$)/.test( script, @@ -108,98 +111,134 @@ function classifyPackage(base, head) { } const event = process.env.GITHUB_EVENT_NAME; -let files = []; -if ( - event === "push" || +if (!["pull_request", "push", "schedule", "workflow_dispatch"].includes(event)) + throw new Error(`Unsupported CI event: ${event}`); +const requestedFull = event === "schedule" || event === "workflow_dispatch" || - process.env.CI_FULL === "true" -) { + process.env.CI_FULL === "true"; +const tier = + event === "schedule" && + process.env.CI_SKIP_FULL === "true" && + process.env.CI_FULL !== "true" + ? "reused" + : requestedFull + ? "full" + : "fast"; +let files = []; +if (tier === "reused") { + reasons.push( + "Recent exact-SHA full qualification reused; no fresh provider observation", + ); +} else if (tier === "full") { full("Full baseline requested by event or ci:full label"); -} else if (event === "pull_request") { - const base = git("merge-base", process.env.BASE_SHA, process.env.HEAD_SHA); +} else if (event === "pull_request" || event === "push") { const head = process.env.HEAD_SHA; - // Disable rename detection so both the removed and added paths participate. - files = git("diff", "--name-only", "--no-renames", "-z", base, head) - .split("\0") - .filter(Boolean); - for (const file of files) { - if ( - /^(README(?:_[^/]+)?\.md|AGENTS\.md|CONTRIBUTING\.md|CHANGELOG\.md|SECURITY\.md|native\/windows\/README\.md|\.github\/pull_request_template\.md)$/.test( - file, - ) || - file.startsWith("docs/") || - file.startsWith(".github/ISSUE_TEMPLATE/") - ) { - selected.docs = true; - selected.website ||= matchesAny(file, SCOPES.website); - continue; - } - if (/^(src|tests)\/.*\.(?:test|spec)\.[cm]?[jt]sx?$/.test(file)) { - selected.code = true; - for (const owner of NATIVE_TEST_OWNERS) - selected[owner] ||= matchesAny(file, SCOPES[owner]); - continue; - } - if (matchesAny(file, MANUAL_VERIFIERS)) { - selected.code = true; - continue; - } - const owners = Object.entries(SCOPES) - .filter(([, patterns]) => - patterns.some((pattern) => matchesGlob(file, pattern)), - ) - .map(([owner]) => owner); - for (const owner of owners) selected[owner] = true; - if ( - file.startsWith(".github/workflows/") || - file === ".github/actionlint.yaml" - ) { - selected.workflows = true; - if (GUARDED_WORKFLOWS.has(file)) selected.code = true; - if (file !== ".github/workflows/ci.yml") continue; - } - if (owners.length === 1 && owners[0] === "website") continue; - if (/^src\/(contracts|domain)\//.test(file)) selected.docs = true; - if (file === "package.json") { - classifyPackage(base, head); - continue; - } - selected.code = true; - if (matchesAny(file, FIXTURE_SOURCES)) { - selected.fixtures = true; - selected.readiness = true; - } - if (matchesAny(file, READINESS_SOURCES)) selected.readiness = true; - if (file.startsWith("tests/")) continue; - if ( - /^(src\/process\/|src\/filesystem\/|src\/contracts\/tool|src\/server\/createServer|src\/cli\.ts|scripts\/ci\/)/.test( - file, - ) - ) { - full(`Shared boundary: ${file}`); - } else if (owners.length) { - if (file.startsWith("src/") || file.startsWith("bridge/")) - selected.runtime = true; - } else if (/^(src|bridge)\//.test(file)) { - // Unowned runtime sources keep the Linux x64 installed-package baseline; - // ci:full, main pushes and manual dispatch retain every native host. - selected.runtime = true; - reasons.push(`Unowned runtime source: ${file}`); - } else if (file.startsWith(".agents/skills/")) { - selected.runtime = true; - selected.docs = true; - } else { - full(`Unclassified input: ${file}`); + let base; + if (event === "pull_request") { + base = git("merge-base", process.env.BASE_SHA, head); + } else { + const candidate = process.env.BASE_SHA; + const baselineReason = process.env.BASELINE_REASON; + try { + if (!candidate || !/^[0-9a-f]{40}$/i.test(candidate)) + throw new Error( + baselineReason || "No valid successful push baseline was found", + ); + execFileSync("git", ["merge-base", "--is-ancestor", candidate, head], { + stdio: "ignore", + }); + base = candidate; + } catch { + full( + baselineReason || + "No valid successful push baseline ancestor; selecting all lanes", + ); } } -} else throw new Error(`Unsupported CI event: ${event}`); + if (base) { + // Disable rename detection so both the removed and added paths participate. + files = git("diff", "--name-only", "--no-renames", "-z", base, head) + .split("\0") + .filter(Boolean); + for (const file of files) { + if ( + /^(README(?:_[^/]+)?\.md|AGENTS\.md|CONTRIBUTING\.md|CHANGELOG\.md|SECURITY\.md|native\/windows\/README\.md|\.github\/pull_request_template\.md)$/.test( + file, + ) || + file.startsWith("docs/") || + file.startsWith(".github/ISSUE_TEMPLATE/") + ) { + selected.docs = true; + selected.website ||= matchesAny(file, SCOPES.website); + continue; + } + if (/^(src|tests)\/.*\.(?:test|spec)\.[cm]?[jt]sx?$/.test(file)) { + selected.code = true; + for (const owner of HOST_TEST_OWNERS) + selected[owner] ||= matchesAny(file, SCOPES[owner]); + continue; + } + if (matchesAny(file, MANUAL_VERIFIERS)) { + selected.code = true; + continue; + } + const owners = Object.entries(SCOPES) + .filter(([, patterns]) => + patterns.some((pattern) => matchesGlob(file, pattern)), + ) + .map(([owner]) => owner); + for (const owner of owners) selected[owner] = true; + if ( + file.startsWith(".github/workflows/") || + file === ".github/actionlint.yaml" + ) { + selected.workflows = true; + if (GUARDED_WORKFLOWS.has(file)) selected.code = true; + if (file !== ".github/workflows/ci.yml") continue; + } + if (owners.length === 1 && owners[0] === "website") continue; + if (/^src\/(contracts|domain)\//.test(file)) selected.docs = true; + if (file === "package.json") { + classifyPackage(base, head); + continue; + } + selected.code = true; + if (matchesAny(file, FIXTURE_SOURCES)) { + selected.fixtures = true; + selected.readiness = true; + } + if (matchesAny(file, READINESS_SOURCES)) selected.readiness = true; + if (file.startsWith("tests/")) continue; + if (PORTABLE_CI_REPORTERS.has(file)) continue; + if ( + /^(src\/process\/|src\/filesystem\/|src\/contracts\/tool|src\/server\/createServer|src\/cli\.ts|scripts\/ci\/)/.test( + file, + ) + ) { + full(`Shared boundary: ${file}`); + } else if (owners.length) { + if (file.startsWith("src/") || file.startsWith("bridge/")) + selected.runtime = true; + } else if (/^(src|bridge)\//.test(file)) { + // Unowned runtime sources keep the Linux x64 installed-package baseline; + // full qualification retains every native host. + selected.runtime = true; + reasons.push(`Unowned runtime source: ${file}`); + } else if (file.startsWith(".agents/skills/")) { + selected.runtime = true; + selected.docs = true; + } else { + full(`Unclassified input: ${file}`); + } + } + } +} selected.runtime ||= selected.package; const linux = { os: "ubuntu-latest", platform: "linux", architecture: "x64" }; -// macOS x64 is the slowest package host. Pull requests run it only with ci:full; -// main pushes, schedules and manual dispatch always include it. +// macOS x64 is the slowest package host. Fast qualification omits it. const intel = - event !== "pull_request" || process.env.CI_FULL === "true" + tier === "full" ? [{ os: "macos-15-intel", platform: "darwin", architecture: "x64" }] : []; const matrix = { @@ -212,17 +251,23 @@ const matrix = { ] : [linux], }; -const plan = { ...selected, matrix, files, reasons }; +const testSelection = planTestSelection(files, event, tier); +const plan = { ...selected, tier, matrix, files, reasons, testSelection }; if (process.env.GITHUB_OUTPUT) appendFileSync( process.env.GITHUB_OUTPUT, - Object.entries({ ...selected, matrix: JSON.stringify(matrix) }) + Object.entries({ + ...selected, + tier, + matrix: JSON.stringify(matrix), + test_selection: JSON.stringify(testSelection), + }) .map(([key, value]) => `${key}=${value}\n`) .join(""), ); if (process.env.GITHUB_STEP_SUMMARY) appendFileSync( process.env.GITHUB_STEP_SUMMARY, - `### Selected CI lanes\n\n${flags.filter((flag) => selected[flag]).join(", ") || "Formatting only"}\n\n${reasons.join("\n\n")}\n`, + `### Selected CI lanes (${tier})\n\n${flags.filter((flag) => selected[flag]).join(", ") || "Formatting only"}\n\n${reasons.join("\n\n")}\n`, ); console.log(JSON.stringify(plan)); diff --git a/scripts/ci/qualification.mjs b/scripts/ci/qualification.mjs new file mode 100644 index 000000000..ab47c168f --- /dev/null +++ b/scripts/ci/qualification.mjs @@ -0,0 +1,176 @@ +import { execFileSync } from "node:child_process"; +import { appendFileSync, mkdirSync, writeFileSync } from "node:fs"; +import { resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const ARTIFACT_NAME = "ci-full-qualification-v1"; +const MAX_AGE_MS = 24 * 60 * 60 * 1000; +const positiveId = (value) => + (typeof value === "string" || typeof value === "number") && + /^[1-9]\d*$/.test(String(value)) && + Number.isSafeInteger(Number(value)); +const commitSha = (value) => + typeof value === "string" && /^[0-9a-f]{40}$/.test(value); + +/** Record only after the required gate has verified every full-tier obligation. */ +export function recordQualification(directory) { + const sourceSha = process.env.GITHUB_SHA; + const runId = process.env.GITHUB_RUN_ID; + const runAttempt = process.env.GITHUB_RUN_ATTEMPT; + const repository = process.env.GITHUB_REPOSITORY; + if ( + !commitSha(sourceSha) || + !positiveId(runId) || + !positiveId(runAttempt) || + !repository + ) + throw new Error( + "Full qualification receipt requires source and workflow identity", + ); + const checkoutSha = execFileSync("git", ["rev-parse", "HEAD"], { + encoding: "utf8", + }).trim(); + if (checkoutSha !== sourceSha) + throw new Error("Qualification checkout differs from workflow source"); + mkdirSync(directory, { recursive: true }); + const path = resolve(directory, "receipt.json"); + writeFileSync( + path, + `${JSON.stringify( + { + schemaVersion: 1, + tier: "full", + sourceSha, + repository, + runId: Number(runId), + runAttempt: Number(runAttempt), + qualifiedAt: new Date().toISOString(), + }, + null, + 2, + )}\n`, + ); + if (process.env.GITHUB_OUTPUT) + appendFileSync( + process.env.GITHUB_OUTPUT, + `receipt_name=${ARTIFACT_NAME}\nreceipt_path=${path}\n`, + ); +} + +function admit() { + if (process.env.CI_FORCE_FULL === "true") + return { + run_full: true, + reason: "Forced daily runner and dependency refresh", + }; + const repository = process.env.CI_REPOSITORY; + const repositoryId = Number(process.env.CI_REPOSITORY_ID); + const branch = process.env.CI_DEFAULT_BRANCH; + const head = process.env.HEAD_SHA; + if (!repository || !positiveId(repositoryId) || !branch || !commitSha(head)) + return { + run_full: true, + reason: "Qualification lookup identity is incomplete", + }; + + const now = Date.now(); + const deadline = now + 20_000; + const api = (...arguments_) => { + const remaining = deadline - Date.now(); + if (remaining <= 0) + throw new Error("Qualification lookup budget exhausted"); + return JSON.parse( + execFileSync("gh", ["api", "--method", "GET", ...arguments_], { + encoding: "utf8", + timeout: Math.min(15_000, remaining), + maxBuffer: 8 * 1024 * 1024, + stdio: ["ignore", "pipe", "pipe"], + }), + ); + }; + try { + const { artifacts } = api( + `repos/${repository}/actions/artifacts`, + "-f", + `name=${ARTIFACT_NAME}`, + "-F", + "per_page=100", + ); + if (!Array.isArray(artifacts)) + throw new Error("Missing qualification artifact inventory"); + const candidates = artifacts.filter((artifact) => { + const lineage = artifact?.workflow_run; + const age = now - Date.parse(artifact?.created_at); + return ( + artifact?.name === ARTIFACT_NAME && + artifact?.expired === false && + typeof artifact?.created_at === "string" && + Number.isFinite(age) && + age >= 0 && + age < MAX_AGE_MS && + positiveId(lineage?.id) && + String(lineage.id) !== process.env.GITHUB_RUN_ID && + lineage?.repository_id === repositoryId && + lineage?.head_repository_id === repositoryId && + lineage?.head_branch === branch && + lineage?.head_sha === head + ); + }); + // Artifact metadata narrows the search before run lookups. Never scan an + // unbounded history or treat a missing receipt as a successful qualification. + for (const artifact of candidates.slice(0, 3)) { + const run = api( + `repos/${repository}/actions/runs/${artifact.workflow_run.id}`, + ); + // An old run can upload a new artifact when only its gate is rerun. + // Bound the original run age as well so retries cannot renew stale proof. + const runAge = Date.now() - Date.parse(run.created_at); + if ( + typeof run.created_at === "string" && + Number.isFinite(runAge) && + runAge >= 0 && + runAge < MAX_AGE_MS && + run.id === artifact.workflow_run.id && + run.status === "completed" && + run.conclusion === "success" && + run.path === ".github/workflows/ci.yml" && + ["schedule", "workflow_dispatch"].includes(run.event) && + run.head_sha === head && + run.head_branch === branch && + run.head_repository?.full_name === repository + ) { + return { + run_full: false, + run_id: run.id, + reason: `Reusing full qualification from run ${run.id}; no fresh provider observation`, + }; + } + } + return { + run_full: true, + reason: "No trusted full qualification for this SHA within 24 hours", + }; + } catch { + return { + run_full: true, + reason: "Qualification lookup unavailable; running full validation", + }; + } +} + +if (resolve(process.argv[1] ?? "") === fileURLToPath(import.meta.url)) { + const decision = admit(); + if (process.env.GITHUB_OUTPUT) + appendFileSync( + process.env.GITHUB_OUTPUT, + Object.entries(decision) + .map(([key, value]) => `${key}=${value}\n`) + .join(""), + ); + if (process.env.GITHUB_STEP_SUMMARY) + appendFileSync( + process.env.GITHUB_STEP_SUMMARY, + `### Scheduled qualification\n\n${decision.reason}.\n`, + ); + console.log(JSON.stringify(decision)); +} diff --git a/scripts/ci/required.mjs b/scripts/ci/required.mjs index 4f6586737..01907de37 100644 --- a/scripts/ci/required.mjs +++ b/scripts/ci/required.mjs @@ -1,18 +1,46 @@ +import { CI_FLAGS } from "./scopes.mjs"; +import { recordQualification } from "./qualification.mjs"; + const jobs = JSON.parse(process.env.CI_JOBS); -const outputs = jobs.changes.outputs; -const required = ["changes", "static", "test"]; +const outputs = jobs?.changes?.outputs; +if (!["fast", "full", "reused"].includes(outputs?.tier)) + throw new Error( + "CI classification requires a valid tier: fast, full, or reused", + ); +const invalidFlags = CI_FLAGS.filter( + (flag) => outputs[flag] !== "true" && outputs[flag] !== "false", +); +if (invalidFlags.length) + throw new Error( + `CI classification requires explicit true/false scope outputs: ${invalidFlags.join(", ")}`, + ); +const selectedScopes = CI_FLAGS.filter((flag) => outputs[flag] === "true"); +const reused = outputs.tier === "reused"; +if ( + reused && + (process.env.GITHUB_EVENT_NAME !== "schedule" || + !/^[1-9]\d*$/.test(outputs.qualification_run_id ?? "") || + !Number.isSafeInteger(Number(outputs.qualification_run_id)) || + selectedScopes.length !== 0) +) + throw new Error( + "Reused qualification requires a scheduled admission receipt and no selected lanes", + ); +if (outputs.tier === "full" && selectedScopes.length !== CI_FLAGS.length) + throw new Error("Full qualification requires every canonical CI scope"); +const required = reused ? ["changes"] : ["changes", "static", "test"]; const lanes = { - code: ["build", "test-shard", "sqlite-runtime"], + code: ["build", "test-shard"], runtime: ["windows-native-build", "package-e2e"], package: ["windows-curated"], + sqlite: ["sqlite-runtime"], apple: ["apple-artifacts"], fixtures: ["conformance-fixtures"], readiness: ["reconstruction-readiness"], docs: ["docs"], + workflows: ["static"], }; -for (const [scope, value] of Object.entries(outputs)) { - if (value === "true") required.push(...(lanes[scope] ?? [scope])); -} +for (const scope of selectedScopes) required.push(...(lanes[scope] ?? [scope])); const failed = [...new Set(required)].filter( (name) => jobs[name]?.result !== "success", ); @@ -23,3 +51,9 @@ for (const [name, job] of Object.entries(jobs)) { if (failed.length) throw new Error(`CI lanes did not pass: ${failed.join(", ")}`); console.log("Every selected CI lane passed"); +if (reused) + console.log( + `Qualification reused from run ${outputs.qualification_run_id}; no fresh provider observation`, + ); +if (outputs.tier === "full" && process.env.CI_QUALIFICATION_DIRECTORY) + recordQualification(process.env.CI_QUALIFICATION_DIRECTORY); diff --git a/scripts/ci/scopes.mjs b/scripts/ci/scopes.mjs index 6207f80ea..a93e0c3bd 100644 --- a/scripts/ci/scopes.mjs +++ b/scripts/ci/scopes.mjs @@ -92,6 +92,55 @@ export const SCOPES = { "tests/boundary/filesystem/javascriptArtifactContentIdentity.test.ts", "tests/boundary/process/sourceMapUncHosts.test.ts", ], + // Native SQLite runtime compatibility for the producer, public adapters, + // fixtures, shared lifecycle, and the package script that defines its suite. + sqlite: [ + "src/sqlite/**", + "src/domain/sqlite/**", + "src/contracts/sqlite/**", + "src/application/sqlite/**", + "src/composition/sqlite.ts", + "src/cli/sqliteCommands.ts", + "src/server/registerSqliteTools.ts", + "src/application/DirectAnalysisStatus*.ts", + "src/application/CapabilityInventory*.ts", + "src/application/AnalysisProvider*.ts", + "src/contracts/toolContracts.ts", + "src/contracts/toolContractTypes.ts", + "src/contracts/toolEffects*.ts", + "src/contracts/toolOutputSchemaPrimitives.ts", + "src/domain/analysisError*.ts", + "src/domain/evidence*.ts", + "src/domain/inputIssueProjection*.ts", + "src/domain/jsonSerialization*.ts", + "src/domain/jsonValue*.ts", + "src/domain/localPath*.ts", + "src/domain/providerAdapterError*.ts", + "src/domain/providerCleanupError*.ts", + "src/domain/result*.ts", + "src/process/OwnedCommand*.ts", + "src/process/ProviderProcess*.ts", + "src/process/PrivateRuntimeRoot*.ts", + "src/artifacts/ArtifactReader*.ts", + "src/artifacts/ArtifactResourceScope*.ts", + "src/artifacts/ArtifactPaths*.ts", + "src/artifacts/readStableArtifact*.ts", + "src/filesystem/OwnedFileHandle*.ts", + "src/server/EvidenceMcpServer*.ts", + "src/server/analysisAdmission*.ts", + "src/server/contractToolHandler*.ts", + "src/server/toolRegistrationOptions*.ts", + "src/server/createServer*.ts", + "src/cli.ts", + "src/cliCommandNames.ts", + "src/cliLogging.ts", + "src/cli/commandCancellation.ts", + "tests/boundary/sqlite/**", + "tests/fixtures/sqlite/**", + "tests/acceptance/sqliteDatabaseCli.test.ts", + "tests/boundary/mcp/serverLifecycleMcp.test.ts", + ".github/workflows/sqlite-runtime.yml", + ], browser: [ ".github/workflows/real-browser.yml", "scripts/verify-real-browser.mjs", @@ -307,6 +356,7 @@ export const SCOPES = { nativeaot: [ "bridge/nativeaot/**", "scripts/generate-nativeaot-fixtures.mjs", + "scripts/lib/nativeaot-build.*", "tests/fixtures/nativeaot/**", ".github/workflows/nativeaot-fixtures.yml", ], @@ -319,6 +369,20 @@ export const SCOPES = { ], }; +export const CI_FLAGS = [ + ...new Set([ + "code", + "runtime", + "package", + "apple", + "fixtures", + "readiness", + "docs", + "workflows", + ...Object.keys(SCOPES), + ]), +]; + // Verifier entrypoints that only manual, licensed, or self-hosted workflows // run. No selected CI lane executes them, so their edits need only the static // checks and the source-test suite. Shared helpers under scripts/lib remain diff --git a/scripts/ci/test-history.mjs b/scripts/ci/test-history.mjs new file mode 100644 index 000000000..4386f48af --- /dev/null +++ b/scripts/ci/test-history.mjs @@ -0,0 +1,114 @@ +import { execFileSync } from "node:child_process"; +import { appendFileSync } from "node:fs"; +import { resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const ARTIFACT_NAME = "test-timings"; +const MAX_AGE_MS = 30 * 24 * 60 * 60 * 1000; +const MAX_CANDIDATES = 5; +const positiveId = (value) => + (typeof value === "string" || typeof value === "number") && + /^[1-9]\d*$/.test(String(value)) && + Number.isSafeInteger(Number(value)); + +function findTimingRun({ repository, branch, repositoryId, now = Date.now() }) { + if ( + !/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repository ?? "") || + !branch || + !positiveId(repositoryId) + ) + return ""; + const deadline = Date.now() + 20_000; + const api = (...arguments_) => { + const remaining = deadline - Date.now(); + if (remaining <= 0) + throw new Error("Timing history lookup budget exhausted"); + return JSON.parse( + execFileSync("gh", ["api", "--method", "GET", ...arguments_], { + encoding: "utf8", + timeout: Math.min(10_000, remaining), + maxBuffer: 4 * 1024 * 1024, + stdio: ["ignore", "pipe", "pipe"], + }), + ); + }; + + const { artifacts } = api( + `repos/${repository}/actions/artifacts`, + "-f", + `name=${ARTIFACT_NAME}`, + "-F", + "per_page=100", + ); + if (!Array.isArray(artifacts)) + throw new Error("Missing timing artifact inventory"); + const candidates = artifacts + .filter((artifact) => { + const lineage = artifact?.workflow_run; + const age = now - Date.parse(artifact?.created_at); + return ( + artifact?.name === ARTIFACT_NAME && + artifact?.expired === false && + typeof artifact?.created_at === "string" && + Number.isFinite(age) && + age >= 0 && + age < MAX_AGE_MS && + positiveId(lineage?.id) && + positiveId(lineage?.repository_id) && + positiveId(lineage?.head_repository_id) && + lineage.repository_id === lineage.head_repository_id && + lineage.repository_id === Number(repositoryId) && + lineage.head_branch === branch + ); + }) + .sort( + (left, right) => + Date.parse(right.created_at) - Date.parse(left.created_at), + ) + .slice(0, MAX_CANDIDATES); + + for (const artifact of candidates) { + const run = api( + `repos/${repository}/actions/runs/${artifact.workflow_run.id}`, + ); + const runAge = now - Date.parse(run?.created_at); + if ( + typeof run?.created_at === "string" && + Number.isFinite(runAge) && + runAge >= 0 && + runAge < MAX_AGE_MS && + run.id === artifact.workflow_run.id && + run.status === "completed" && + run.conclusion === "success" && + run.path === ".github/workflows/ci.yml" && + ["schedule", "workflow_dispatch"].includes(run.event) && + run.head_branch === branch && + run.head_repository?.full_name === repository + ) + return String(run.id); + } + return ""; +} + +function write(runId) { + if (process.env.GITHUB_OUTPUT) + appendFileSync(process.env.GITHUB_OUTPUT, `run-id=${runId}\n`); + console.log(JSON.stringify({ run_id: runId })); +} + +if ( + process.argv[1] && + fileURLToPath(import.meta.url) === resolve(process.argv[1]) +) { + let runId = ""; + try { + runId = findTimingRun({ + repository: process.env.CI_REPOSITORY, + branch: process.env.CI_DEFAULT_BRANCH, + repositoryId: process.env.CI_REPOSITORY_ID, + }); + } catch { + // History improves shard ordering but must never block CI. + } + write(runId); +} diff --git a/scripts/ci/test-report.mjs b/scripts/ci/test-report.mjs index a3686d6ed..035a01990 100644 --- a/scripts/ci/test-report.mjs +++ b/scripts/ci/test-report.mjs @@ -1,28 +1,36 @@ +import { execFileSync } from "node:child_process"; import { appendFile, mkdir, readFile, rm, writeFile } from "node:fs/promises"; import { isAbsolute, join, relative, resolve, sep } from "node:path"; import { z } from "zod"; +import { compareTestSelection } from "./test-selection.mjs"; + const root = process.cwd(); const historyDirectory = join(root, ".cache/ci-test-history"); const historyPath = join(historyDirectory, "test-results.json"); +const selectionDirectory = join(root, ".cache/ci-test-selection"); +const selectionPath = join(selectionDirectory, "report.json"); // Never let a failed or partial rerun leave a previous successful history file. await rm(historyPath, { force: true }); +await rm(selectionPath, { force: true }); const report = z .object({ + version: z.literal(1), success: z.boolean(), - numFailedTests: z.number().int().nonnegative(), - testResults: z.array( + reason: z.string().optional(), + unhandledErrors: z.number().int().nonnegative().optional(), + files: z.array( z.object({ name: z.string().min(1), - startTime: z.number().finite(), - endTime: z.number().finite(), + durationMs: z.number().finite().nonnegative(), + state: z.string().optional(), }), ), }) - .parse(JSON.parse(await readFile("test-results.json", "utf8"))); + .parse(JSON.parse(await readFile("test-timings.json", "utf8"))); -const files = report.testResults.map(({ name, startTime, endTime }) => { +const files = report.files.map(({ name, durationMs, state }) => { const path = relative(root, resolve(root, name)); if ( path === "" || @@ -31,32 +39,85 @@ const files = report.testResults.map(({ name, startTime, endTime }) => { isAbsolute(path) ) throw new Error(`Test report path is outside the checkout: ${name}`); - const duration = endTime - startTime; - if (!Number.isFinite(duration) || duration < 0) - throw new Error(`Test report has an invalid duration: ${name}`); - return { name: path.split(sep).join("/"), startTime: 0, endTime: duration }; + return { name: path.split(sep).join("/"), durationMs, state }; }); const complete = process.env.SHARD_RESULT === "success"; const passed = - complete && - process.env.MERGE_RESULT === "success" && - report.success && - report.numFailedTests === 0; + complete && process.env.MERGE_RESULT === "success" && report.success; +// Successful shards and merged reports must account for the complete portable +// inventory. Coverage thresholds alone cannot prove that every file ran. +const verifyInventory = process.env.CI_VERIFY_TEST_INVENTORY === "true"; +const expected = + verifyInventory || process.env.CI_TEST_SELECTION + ? execFileSync("git", ["ls-files", "-z", "--", "src", "tests"], { + encoding: "utf8", + maxBuffer: 8 * 1024 * 1024, + }) + .split("\0") + .filter((path) => path.endsWith(".test.ts")) + : []; +let selection; +if (process.env.CI_TEST_SELECTION) { + const comparison = compareTestSelection( + JSON.parse(process.env.CI_TEST_SELECTION), + expected, + files, + ); + selection = { + ...comparison, + complete: + comparison.complete && + report.unhandledErrors === 0 && + ["passed", "failed"].includes(report.reason) && + ["success", "failure"].includes(process.env.SHARD_RESULT) && + ["success", "failure"].includes(process.env.MERGE_RESULT), + executionSha: process.env.GITHUB_SHA ?? null, + prHeadSha: process.env.CI_PR_HEAD_SHA ?? null, + runId: process.env.GITHUB_RUN_ID ?? null, + runAttempt: process.env.GITHUB_RUN_ATTEMPT ?? null, + }; + await mkdir(selectionDirectory, { recursive: true }); + await writeFile(selectionPath, JSON.stringify(selection)); +} +if (passed && verifyInventory) { + const actual = files.map(({ name }) => name); + const expectedSet = new Set(expected); + const actualSet = new Set(actual); + const missing = expected.filter((path) => !actualSet.has(path)); + const unexpected = actual.filter((path) => !expectedSet.has(path)); + if (missing.length || unexpected.length || actualSet.size !== actual.length) + throw new Error( + `Incomplete portable test inventory: ${JSON.stringify({ missing, unexpected, duplicateFiles: actual.length - actualSet.size })}`, + ); +} const summary = [ complete ? "## Merged test diagnostics" : "## Partial test diagnostics", "", + ...(selection + ? [ + "### Observational PR test selection", + "", + `Plan: ${selection.plan.mode}. Proposed files: ${selection.selected.length}; omitted: ${selection.omitted.length}.`, + `Full-run comparison: ${selection.complete ? "complete" : "incomplete"}; failures outside proposed selection: ${selection.missedFailures.length}.`, + "The complete suite still ran. This report cannot enable omissions or qualify a revision. Skipped, missing, and interrupted observations do not establish parity.", + "", + ] + : []), `Shard result: ${process.env.SHARD_RESULT ?? "unknown"}; merge result: ${process.env.MERGE_RESULT ?? "unknown"}.`, passed ? "Successful timing history is available." : "This report is diagnostic only and is not a successful timing baseline.", "", + "Durations include tests and hooks, worker preparation, environment, imports, and setup. They are scheduling weights, not summed workflow wall time.", + "", "| Slowest file | Duration (ms) |", "| --- | ---: |", ...files - .toSorted((left, right) => right.endTime - left.endTime) + .toSorted((left, right) => right.durationMs - left.durationMs) .slice(0, 20) .map( - ({ name, endTime }) => `| ${name.replaceAll("|", "\\|")} | ${endTime} |`, + ({ name, durationMs }) => + `| ${name.replaceAll("|", "\\|")} | ${durationMs} |`, ), "", ].join("\n"); @@ -68,6 +129,10 @@ if (passed) { await mkdir(historyDirectory, { recursive: true }); await writeFile( historyPath, - JSON.stringify({ success: true, numFailedTests: 0, testResults: files }), + JSON.stringify({ + version: 1, + success: true, + files: files.map(({ name, durationMs }) => ({ name, durationMs })), + }), ); } diff --git a/scripts/ci/test-selection.d.mts b/scripts/ci/test-selection.d.mts new file mode 100644 index 000000000..c19414398 --- /dev/null +++ b/scripts/ci/test-selection.d.mts @@ -0,0 +1,35 @@ +export interface TestSelectionPlan { + readonly version: 1; + readonly mode: "full" | "candidate"; + readonly owners: readonly string[]; + readonly changedTests: readonly string[]; + readonly changedPaths: readonly string[]; + readonly reason: string; +} +export function planTestSelection( + files: readonly string[], + event: string, + tier: string, +): TestSelectionPlan; +export function compareTestSelection( + plan: unknown, + inventory: readonly string[], + results: readonly { + readonly name: string; + readonly durationMs: number; + readonly state?: string; + }[], +): { + readonly version: 1; + readonly observational: true; + readonly plan: TestSelectionPlan; + readonly selected: readonly string[]; + readonly omitted: readonly string[]; + readonly missing: readonly string[]; + readonly unexpected: readonly string[]; + readonly duplicateFiles: number; + readonly unobserved: readonly string[]; + readonly missedFailures: readonly string[]; + readonly complete: boolean; + readonly omittedDurationMs: number; +}; diff --git a/scripts/ci/test-selection.mjs b/scripts/ci/test-selection.mjs new file mode 100644 index 000000000..8165e3658 --- /dev/null +++ b/scripts/ci/test-selection.mjs @@ -0,0 +1,151 @@ +import { matchesGlob } from "node:path"; + +// Candidate ownership only: these leaf adapters and their producer tests can be +// compared with full-suite outcomes. This table never changes test execution. +// Shared application/domain code and dynamic CLI/MCP consumers are not leaf owners. +const OWNERS = { + adb: ["src/adb/**", "tests/boundary/providers/adb/**"], + apktool: ["src/apktool/**"], + dotnet: ["src/dotnet/**"], + evm: ["src/evm/**", "tests/boundary/evm/**"], + firmware: ["src/firmware/**", "tests/boundary/firmware/**"], + flutter: ["src/flutter/**"], + ghidra: ["src/ghidra/**", "tests/boundary/providers/ghidra/**"], + hopper: ["src/hopper/**", "tests/boundary/providers/hopper/**"], + ida: ["src/ida/**", "tests/boundary/providers/ida/**"], + jeb: ["src/jeb/**"], + pcap: ["src/pcap/**", "tests/boundary/pcap/**"], + sqlite: ["src/sqlite/**", "tests/boundary/sqlite/**"], + wasm: ["src/wasm/**"], +}; +const ownersOf = (path) => + Object.entries(OWNERS) + .filter(([, patterns]) => patterns.some((glob) => matchesGlob(path, glob))) + .map(([owner]) => owner); +const validPath = (path) => + typeof path === "string" && + /^(src|tests)\//.test(path) && + !/[\\\0\r\n]/.test(path) && + !path.split("/").some((part) => ["", ".", ".."].includes(part)); +const full = (reason, changedPaths = []) => ({ + version: 1, + mode: "full", + owners: [], + changedTests: [], + changedPaths, + reason, +}); + +/** Plan an observational PR subset from the classifier's existing Git diff. */ +export function planTestSelection(files, event, tier) { + if (event !== "pull_request" || tier !== "fast") + return full("Only ordinary PRs are candidates", files); + if (!files.length) return full("No changed paths available"); + const owners = new Set(); + const changedTests = []; + for (const path of files) { + if (!validPath(path)) + return full(`Shared or unknown input: ${path}`, files); + const matches = ownersOf(path); + if (!matches.length) return full(`Shared or unknown input: ${path}`, files); + for (const owner of matches) owners.add(owner); + if (path.endsWith(".test.ts")) changedTests.push(path); + } + return { + version: 1, + mode: "candidate", + owners: [...owners].sort(), + changedTests: [...new Set(changedTests)].sort(), + changedPaths: files, + reason: + "Observe affected leaf owners; retain integration and unowned tests", + }; +} + +/** Compare a proposal with the full run; missing observations never prove parity. */ +export function compareTestSelection(plan, inventory, results) { + if ( + plan?.version !== 1 || + !["full", "candidate"].includes(plan.mode) || + !Array.isArray(plan.owners) || + plan.owners.some((owner) => !Object.hasOwn(OWNERS, owner)) || + !Array.isArray(plan.changedTests) || + !Array.isArray(plan.changedPaths) || + plan.changedPaths.some((path) => typeof path !== "string") || + plan.changedTests.some( + (path) => !validPath(path) || !path.endsWith(".test.ts"), + ) || + typeof plan.reason !== "string" || + (plan.mode === "candidate" && !plan.owners.length) || + (plan.mode === "full" && (plan.owners.length || plan.changedTests.length)) + ) + throw new Error("Invalid observational test selection plan"); + const expected = new Set(inventory); + if (!expected.size || expected.size !== inventory.length) + throw new Error("Test selection requires a nonempty unique inventory"); + const ownersByFile = new Map( + plan.mode === "candidate" + ? inventory.map((path) => [path, ownersOf(path)]) + : [], + ); + // Removed/renamed tests have no current executable identity. Keep all tests. + const removed = plan.changedTests.filter((path) => !expected.has(path)); + const missingOwners = plan.owners.filter( + (owner) => + ![...ownersByFile.values()].some((owners) => owners.includes(owner)), + ); + const effective = removed.length + ? full( + `Changed tests absent from current inventory: ${removed.join(", ")}`, + plan.changedPaths, + ) + : missingOwners.length + ? full( + `Owners without executable tests: ${missingOwners.join(", ")}`, + plan.changedPaths, + ) + : plan; + const selected = []; + const omitted = []; + for (const path of inventory.toSorted()) { + const owners = ownersByFile.get(path) ?? []; + const keep = + effective.mode === "full" || + !owners.length || + effective.changedTests.includes(path) || + owners.some((owner) => effective.owners.includes(owner)); + (keep ? selected : omitted).push(path); + } + const actual = new Set(results.map((file) => file.name)); + const missing = inventory.filter((path) => !actual.has(path)); + const unexpected = [...actual].filter((path) => !expected.has(path)); + const duplicateFiles = results.length - actual.size; + const unobserved = results + .filter((file) => !["passed", "failed"].includes(file.state)) + .map((file) => file.name); + const omittedSet = new Set(omitted); + const missedFailures = results + .filter((file) => omittedSet.has(file.name) && file.state === "failed") + .map((file) => file.name); + return { + version: 1, + observational: true, + plan: effective, + selected, + omitted, + missing, + unexpected, + duplicateFiles, + unobserved, + missedFailures, + complete: + !missing.length && + !unexpected.length && + !duplicateFiles && + !unobserved.length, + // Phase totals are scheduling weights, not an estimate of wall-time savings. + omittedDurationMs: results + .filter((file) => omittedSet.has(file.name)) + .reduce((sum, file) => sum + file.durationMs, 0), + }; +} diff --git a/scripts/ci/test-timing-reporter.mjs b/scripts/ci/test-timing-reporter.mjs new file mode 100644 index 000000000..ce0b1c5dc --- /dev/null +++ b/scripts/ci/test-timing-reporter.mjs @@ -0,0 +1,43 @@ +import { writeFile } from "node:fs/promises"; + +/** @implements {import("vitest/node").Reporter} */ +export default class TestTimingReporter { + /** + * @param {ReadonlyArray} modules + * @param {ReadonlyArray} errors + * @param {import("vitest/node").TestRunEndReason} reason + */ + async onTestRunEnd(modules, errors, reason) { + const files = modules.map((module) => { + const diagnostic = module.diagnostic(); + // These disjoint phases match Vitest's per-file wall-time accounting. + // Import timings already include transform waits; do not add them again. + const phases = { + execution: diagnostic.duration, + preparation: diagnostic.prepareDuration, + environment: diagnostic.environmentSetupDuration, + imports: diagnostic.collectDuration, + setup: diagnostic.setupDuration, + }; + return { + name: module.moduleId, + state: module.state(), + durationMs: Object.values(phases).reduce( + (total, value) => total + value, + 0, + ), + phases, + }; + }); + await writeFile( + "test-timings.json", + JSON.stringify({ + version: 1, + success: reason === "passed" && errors.length === 0, + reason, + unhandledErrors: errors.length, + files, + }), + ); + } +} diff --git a/scripts/ci/verified-package.mjs b/scripts/ci/verified-package.mjs new file mode 100644 index 000000000..1053760b2 --- /dev/null +++ b/scripts/ci/verified-package.mjs @@ -0,0 +1,235 @@ +import { createHash } from "node:crypto"; +import { createReadStream } from "node:fs"; +import { execFile } from "node:child_process"; +import { copyFile, readFile, writeFile } from "node:fs/promises"; +import { join, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; +import { promisify } from "node:util"; + +const MANIFEST_NAME = "manifest.json"; +const TARBALL_NAME = "package.tgz"; +const MANIFEST_KEYS = [ + "schemaVersion", + "sourceSha", + "runId", + "runAttempt", + "platform", + "architecture", + "packageVersion", + "nodeVersion", + "sha256", +].sort(); +const execFileAsync = promisify(execFile); + +/** Normalize workflow identity and host facts into the manifest-owned fields. */ +export function createVerifiedPackageMetadata({ + sourceSha, + runId, + runAttempt, + platform, + architecture, + packageVersion, + nodeVersion, +}) { + if (!/^[a-f0-9]{40}$/u.test(sourceSha)) + throw new Error("Source SHA must be a full commit SHA"); + return { + sourceSha, + runId: parsePositiveInteger(runId, "GITHUB_RUN_ID"), + runAttempt: parsePositiveInteger(runAttempt, "GITHUB_RUN_ATTEMPT"), + platform, + architecture, + packageVersion, + nodeVersion, + }; +} + +/** Build the single supported manifest representation for a verified tarball. */ +function createVerifiedPackageManifest(metadata) { + const manifest = { schemaVersion: 1, ...metadata }; + validateManifestShape(manifest); + return manifest; +} + +/** Write a manifest after the caller has completed qualification and cleanup. */ +export async function writeVerifiedPackageManifest(directory, metadata) { + const manifest = createVerifiedPackageManifest(metadata); + await writeFile( + join(directory, MANIFEST_NAME), + `${JSON.stringify(manifest, null, 2)}\n`, + { encoding: "utf8" }, + ); + return manifest; +} + +/** Copy the qualified archive under its fixed name and prepare its manifest. */ +export async function retainVerifiedPackage({ + sourceTarball, + directory, + metadata, +}) { + const tarball = join(directory, TARBALL_NAME); + await copyFile(sourceTarball, tarball); + const sha256 = await sha256File(tarball); + return { + directory, + metadata: createVerifiedPackageManifest({ ...metadata, sha256 }), + }; +} + +/** Validate a retained package against the current checkout and workflow attempt. */ +async function validateVerifiedPackage({ + directory, + sourceSha, + runId, + runAttempt, + packageVersion, + nodeVersion, +}) { + if (!/^[a-f0-9]{40}$/u.test(sourceSha)) + throw new Error("Expected source SHA must be a full commit SHA"); + if (!Number.isSafeInteger(runId) || runId <= 0) + throw new Error("Expected workflow run ID must be a positive integer"); + if (!Number.isSafeInteger(runAttempt) || runAttempt <= 0) + throw new Error("Expected workflow run attempt must be a positive integer"); + const manifestPath = join(directory, MANIFEST_NAME); + let manifest; + try { + manifest = JSON.parse(await readFile(manifestPath, "utf8")); + } catch (cause) { + throw new Error(`Could not read verified package manifest: ${cause}`, { + cause, + }); + } + validateManifestShape(manifest); + assertEqual(manifest.sourceSha, sourceSha, "source SHA"); + assertEqual(manifest.runId, runId, "workflow run ID"); + // A successful producer may belong to an earlier attempt when only failed + // publisher jobs are rerun. The workflow still requires same-run qualification. + if (manifest.runAttempt > runAttempt) + throw new Error("Verified package workflow run attempt is from the future"); + assertEqual(manifest.platform, "linux", "verifier platform"); + assertEqual(manifest.architecture, "x64", "verifier architecture"); + assertEqual(manifest.packageVersion, packageVersion, "package version"); + assertEqual(manifest.nodeVersion, nodeVersion, "Node.js version"); + + // The artifact format deliberately fixes the name; no manifest value can + // redirect validation to another path. + const tarball = resolve(directory, TARBALL_NAME); + const digest = await sha256File(tarball); + assertEqual(manifest.sha256, digest, "tarball SHA-256"); + return tarball; +} + +function validateManifestShape(manifest) { + if ( + typeof manifest !== "object" || + manifest === null || + Array.isArray(manifest) + ) + throw new Error("Verified package manifest must be a JSON object"); + const keys = Object.keys(manifest).sort(); + if ( + keys.length !== MANIFEST_KEYS.length || + keys.some((key, index) => key !== MANIFEST_KEYS[index]) + ) + throw new Error("Verified package manifest has missing or unknown fields"); + if (manifest.schemaVersion !== 1) + throw new Error("Unsupported verified package manifest schema version"); + if ( + typeof manifest.sourceSha !== "string" || + !/^[a-f0-9]{40}$/u.test(manifest.sourceSha) + ) + throw new Error("Verified package manifest has an invalid source SHA"); + if (!Number.isSafeInteger(manifest.runId) || manifest.runId <= 0) + throw new Error("Verified package manifest has an invalid workflow run ID"); + if (!Number.isSafeInteger(manifest.runAttempt) || manifest.runAttempt <= 0) + throw new Error( + "Verified package manifest has an invalid workflow run attempt", + ); + for (const key of [ + "platform", + "architecture", + "packageVersion", + "nodeVersion", + ]) + if (typeof manifest[key] !== "string" || manifest[key].length === 0) + throw new Error(`Verified package manifest has an invalid ${key}`); + if ( + typeof manifest.sha256 !== "string" || + !/^[a-f0-9]{64}$/u.test(manifest.sha256) + ) + throw new Error("Verified package manifest has an invalid tarball SHA-256"); +} + +function assertEqual(actual, expected, label) { + if (actual !== expected) + throw new Error(`Verified package ${label} mismatch`); +} + +async function sha256File(path) { + const hash = createHash("sha256"); + for await (const chunk of createReadStream(path)) hash.update(chunk); + return hash.digest("hex"); +} + +async function validateFromCli(directory) { + const sourceSha = process.env.GITHUB_SHA; + const runId = parsePositiveInteger( + process.env.GITHUB_RUN_ID, + "GITHUB_RUN_ID", + ); + const runAttempt = parsePositiveInteger( + process.env.GITHUB_RUN_ATTEMPT, + "GITHUB_RUN_ATTEMPT", + ); + if (sourceSha === undefined || !/^[a-f0-9]{40}$/u.test(sourceSha)) + throw new Error("GITHUB_SHA must be a full commit SHA"); + const checkoutSha = ( + await execFileAsync("git", ["rev-parse", "HEAD"]) + ).stdout.trim(); + assertEqual(checkoutSha, sourceSha, "checked out source SHA"); + const packageJson = JSON.parse(await readFile("package.json", "utf8")); + const tarball = await validateVerifiedPackage({ + directory, + sourceSha, + runId, + runAttempt, + packageVersion: packageJson.version, + nodeVersion: process.version, + }); + if (process.env.GITHUB_OUTPUT === undefined) + throw new Error( + "GITHUB_OUTPUT is required to publish the validated tarball path", + ); + await writeFile(process.env.GITHUB_OUTPUT, `tarball=${tarball}\n`, { + encoding: "utf8", + flag: "a", + }); + process.stdout.write(`${tarball}\n`); +} + +function parsePositiveInteger(value, name) { + if (value === undefined || !/^[1-9]\d*$/u.test(value)) + throw new Error(`${name} must be a positive integer`); + const parsed = Number(value); + if (!Number.isSafeInteger(parsed)) + throw new Error(`${name} must be a safe positive integer`); + return parsed; +} + +const invokedPath = process.argv[1]; +if ( + invokedPath !== undefined && + resolve(invokedPath) === fileURLToPath(import.meta.url) +) { + const [command, directory, ...extra] = process.argv.slice(2); + if (command !== "validate" || directory === undefined || extra.length > 0) { + process.stderr.write( + "Usage: node scripts/ci/verified-package.mjs validate \n", + ); + process.exitCode = 2; + } else { + await validateFromCli(directory); + } +} diff --git a/scripts/generate-nativeaot-fixtures.mjs b/scripts/generate-nativeaot-fixtures.mjs index 84a8ac533..fa9127cf3 100644 --- a/scripts/generate-nativeaot-fixtures.mjs +++ b/scripts/generate-nativeaot-fixtures.mjs @@ -4,9 +4,14 @@ import { createHash } from "node:crypto"; import { copyFile, mkdir, readFile, writeFile } from "node:fs/promises"; import { dirname, join, resolve } from "node:path"; import { fileURLToPath } from "node:url"; +import { + buildNativeAotFixture, + nativeAotCommandError, + supportsNativeAotFixtureHost, +} from "./lib/nativeaot-build.mjs"; const root = resolve(dirname(fileURLToPath(import.meta.url)), ".."); -if (process.arch !== "x64" || !["linux", "win32"].includes(process.platform)) +if (!supportsNativeAotFixtureHost(process.platform, process.arch)) throw new Error( "NativeAOT fixture lane requires Linux or Windows x64; it does not cross-compile NativeAOT.", ); @@ -40,9 +45,7 @@ const run = (command, args) => { maxBuffer: 8 * 1024 * 1024, }); if (result.error || result.status !== 0) - throw new Error( - `NativeAOT fixture lane requires/action failed ${command}: ${result.error?.message ?? ""}\n${result.stdout ?? ""}${result.stderr ?? ""}`, - ); + throw nativeAotCommandError(command, args[0], result); return result.stdout; }; const dotnet = process.env.REA_NATIVEAOT_DOTNET ?? "dotnet"; @@ -57,20 +60,12 @@ if (process.platform === "linux") { run("clang", ["--version"]); } const map = join(output, "NativeAotFixture.map"); -run(dotnet, [ - "publish", - join(root, "tests/fixtures/nativeaot/NativeAotFixture.csproj"), - "-r", +await buildNativeAotFixture(run, { + dotnet, + project: join(root, "tests/fixtures/nativeaot/NativeAotFixture.csproj"), runtime, - "-c", - "Release", - "-o", - join(output, "symbols"), - "--maxcpucount:1", - `-p:BaseIntermediateOutputPath=${join(output, "obj")}/`, - `-p:BaseOutputPath=${join(output, "bin")}/`, - `-p:NativeAotMapPath=${map}`, -]); + output, +}); const name = process.platform === "win32" ? "NativeAotFixture.exe" : "NativeAotFixture"; const binary = join(output, "symbols", name); diff --git a/scripts/lib/nativeaot-build.d.mts b/scripts/lib/nativeaot-build.d.mts new file mode 100644 index 000000000..418111852 --- /dev/null +++ b/scripts/lib/nativeaot-build.d.mts @@ -0,0 +1,25 @@ +export function supportsNativeAotFixtureHost( + platform: string, + architecture: string, +): boolean; + +export function buildNativeAotFixture( + run: (command: string, args: string[]) => unknown, + options: { + dotnet: string; + project: string; + runtime: string; + output: string; + }, +): Promise; + +export function nativeAotCommandError( + command: string, + operation: string, + result: { + error?: { message: string }; + status: number | null; + stdout?: string | null; + stderr?: string | null; + }, +): Error; diff --git a/scripts/lib/nativeaot-build.mjs b/scripts/lib/nativeaot-build.mjs new file mode 100644 index 000000000..3b49ce839 --- /dev/null +++ b/scripts/lib/nativeaot-build.mjs @@ -0,0 +1,60 @@ +import { join } from "node:path"; +import { setTimeout as delay } from "node:timers/promises"; + +/** NativeAOT fixtures use native toolchains, not cross-compilation. */ +export function supportsNativeAotFixtureHost(platform, architecture) { + return architecture === "x64" && ["linux", "win32"].includes(platform); +} + +/** Keep network recovery separate from compilation and preserve restore failures. */ +export async function buildNativeAotFixture(run, options) { + const { dotnet, project, runtime, output } = options; + const common = [ + project, + "-r", + runtime, + "--maxcpucount:1", + "-p:Configuration=Release", + `-p:BaseIntermediateOutputPath=${join(output, "obj")}/`, + `-p:BaseOutputPath=${join(output, "bin")}/`, + `-p:NativeAotMapPath=${join(output, "NativeAotFixture.map")}`, + ]; + for (let attempt = 1; attempt <= 2; attempt++) { + console.error(`NativeAOT dependency restore: attempt ${attempt}/2`); + try { + run(dotnet, ["restore", ...common, "--verbosity", "normal"]); + break; + } catch (cause) { + if (attempt === 2) + throw new Error( + "NativeAOT dependency restore failed after two attempts", + { + cause, + }, + ); + // Child diagnostics can contain authenticated feed URLs; keep retry logs static. + console.error( + "NativeAOT dependency restore failed; retrying in 1 second", + ); + await delay(1_000); + } + } + console.error("NativeAOT compilation (dependencies already restored)"); + run(dotnet, [ + "publish", + ...common, + "--no-restore", + "-o", + join(output, "symbols"), + ]); +} + +/** Sanitize child diagnostics before any retry, cause chain, or uncaught output. */ +export function nativeAotCommandError(command, operation, result) { + const diagnostic = `NativeAOT fixture lane requires/action failed ${command} ${operation}: ${result.error?.message ?? `exit ${result.status}`}\n${result.stdout ?? ""}${result.stderr ?? ""}`; + // Only URL authority userinfo is authentication; preserve host, path, query, + // and unrelated diagnostic values. Never retain the raw result as a cause. + return new Error( + diagnostic.replace(/\b(https?:\/\/)[^\\\s/?#]*@/giu, "$1[redacted]@"), + ); +} diff --git a/scripts/lib/real-ghidra-file-offsets.mjs b/scripts/lib/real-ghidra-file-offsets.mjs new file mode 100644 index 000000000..ea881dd04 --- /dev/null +++ b/scripts/lib/real-ghidra-file-offsets.mjs @@ -0,0 +1,264 @@ +import assert from "node:assert/strict"; +import { execFile } from "node:child_process"; +import { + mkdir, + mkdtemp, + readFile, + readdir, + rm, + writeFile, +} from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { promisify } from "node:util"; +import { Client } from "@modelcontextprotocol/client"; +import { StdioClientTransport } from "@modelcontextprotocol/client/stdio"; +import { parseEvidence } from "../../dist/domain/evidence.js"; +import { + requireMcpOperationResult, + requireMcpToolError, + mcpTextValue, +} from "./mcp-verifier-results.mjs"; + +/** Exercise file coordinates through public CLI/MCP using the source-owned PE fixture. */ +export async function verifyGhidraFileOffsets( + targetPath, + entrypoint, + procedure, +) { + const original = await readFile(targetPath); + const workspace = await mkdtemp(join(tmpdir(), "rea-file-offsets-")); + const runtime = join(workspace, "runtime"); + await mkdir(runtime); + const env = { + ...process.env, + TEMP: runtime, + TMP: runtime, + TMPDIR: runtime, + REA_ANALYSIS_PROVIDER: "ghidra", + REA_LOG_LEVEL: "silent", + }; + const client = new Client({ name: "rea-file-offsets", version: "1" }); + const transport = new StdioClientTransport({ + command: process.execPath, + args: [entrypoint, "mcp"], + env, + stderr: "pipe", + }); + let connected = false; + let complete = false; + let primaryFailure; + const call = async (name, arguments_ = {}) => { + const result = await client.callTool( + { name, arguments: arguments_ }, + { timeout: 240_000 }, + ); + const projected = requireMcpOperationResult(result, name); + return ["open_binary", "binary_session", "close_binary"].includes(name) + ? projected + : (result.structuredContent ?? JSON.parse(mcpTextValue(result))); + }; + try { + await client.connect(transport); + connected = true; + await call("open_binary", { path: targetPath, provider_id: "ghidra" }); + const session = await call("binary_session"); + const mapping = parseEvidence( + await call("address_to_file_offset", { address: procedure }), + ); + const offset = mapping.normalized_result.file_offset; + const coordinate = `0x${offset.toString(16)}`; + const expected = parseEvidence( + await call("procedure_pseudo_code", { procedure }), + ); + const explicit = parseEvidence( + await call("procedure_pseudo_code", { + procedure: `file-offset:${coordinate}`, + }), + ); + const automatic = parseEvidence( + await call("procedure_pseudo_code", { procedure: coordinate }), + ); + for (const actual of [explicit, automatic]) { + assert.equal(actual.normalized_result, expected.normalized_result); + assert.equal(actual.raw_result.selection.file_offset, offset); + assert.equal(actual.raw_result.selection.mapped_address, procedure); + assert.ok( + actual.locations.some( + (location) => + location.kind === "file-offset" && location.offset === offset, + ), + ); + } + const invalid = await client.callTool({ + name: "procedure_pseudo_code", + arguments: { procedure: "file-offset:0x20000000000000" }, + }); + assert.equal(requireMcpToolError(invalid).code, "invalid_request"); + const unmapped = await client.callTool({ + name: "procedure_pseudo_code", + arguments: { procedure: "file-offset:0x100000" }, + }); + assert.ok( + JSON.stringify(requireMcpToolError(unmapped)).includes( + "no loaded source mapping", + ), + ); + assert.equal( + (await call("binary_session")).analysis_run.run_id, + session.analysis_run.run_id, + ); + const image = parseEvidence(await call("inspect_native_load_image")); + const headerMapping = image.normalized_result.observations.mappings.find( + (item) => item.initialized && item.file_offset === 0, + ); + assert.ok( + headerMapping, + "Fixture header must have an observed source mapping", + ); + const headerOffset = parseEvidence( + await call("address_to_file_offset", { address: headerMapping.start }), + ); + assert.equal(headerOffset.normalized_result.file_offset, 0); + for (const selector of ["file-offset:0x0", "0x0"]) { + const missing = requireMcpToolError( + await client.callTool({ + name: "procedure_pseudo_code", + arguments: { procedure: selector }, + }), + ); + assertMissingMappedProcedure(missing, headerMapping.start); + } + assert.equal( + (await call("binary_session")).analysis_run.run_id, + session.analysis_run.run_id, + ); + await call("close_binary"); + const cli = JSON.parse( + ( + await promisify(execFile)( + process.execPath, + [ + entrypoint, + "decompile", + targetPath, + `--file-offset=${coordinate}`, + "--provider", + "ghidra", + "--json", + ], + { env, timeout: 240_000, maxBuffer: 16 * 1024 * 1024 }, + ) + ).stdout, + ); + assert.equal(cli.normalized_result, explicit.normalized_result); + assert.deepEqual(cli.locations, explicit.locations); + const missingCli = await promisify(execFile)( + process.execPath, + [ + entrypoint, + "decompile", + targetPath, + "--file-offset=0x0", + "--provider", + "ghidra", + "--json", + ], + { env, timeout: 240_000, maxBuffer: 16 * 1024 * 1024 }, + ).then( + () => { + throw new Error( + "Mapped header bytes must not decompile as a procedure", + ); + }, + (cause) => JSON.parse(cause.stdout), + ); + assertMissingMappedProcedure(missingCli, headerMapping.start); + const alias = Buffer.from(original); + const pe = alias.readUInt32LE(0x3c); + if (alias.readUInt16LE(pe + 6) >= 2) { + const secondSection = pe + 24 + alias.readUInt16LE(pe + 20) + 40; + // Both sections now carry the same original bytes at distinct virtual addresses. + alias.writeUInt32LE(0x200, secondSection + 20); + const ambiguousPath = join(workspace, "ambiguous.exe"); + await writeFile(ambiguousPath, alias); + await call("open_binary", { path: ambiguousPath, provider_id: "ghidra" }); + const ambiguous = await client.callTool( + { + name: "procedure_pseudo_code", + arguments: { procedure: `file-offset:${coordinate}` }, + }, + { timeout: 240_000 }, + ); + assert.ok( + JSON.stringify(requireMcpToolError(ambiguous)).includes( + "multiple loaded mappings", + ), + ); + await call("close_binary"); + } + assert.deepEqual(await readFile(targetPath), original); + await client.close(); + connected = false; + assert.deepEqual(await readdir(runtime), []); + complete = true; + return { + cli_mcp_parity: true, + explicit_and_numeric_offsets: true, + invalid_and_unmapped_offsets: true, + mapped_offset_without_procedure: true, + ambiguous_mappings: + alias.readUInt16LE(pe + 6) >= 2 + ? "verified" + : "unavailable-single-section", + source_unchanged: true, + cleanup: "complete", + }; + } catch (cause) { + primaryFailure = cause; + throw cause; + } finally { + const cleanupFailures = []; + if (connected) { + try { + await call("close_binary"); + } catch (cause) { + cleanupFailures.push(cause); + } + } + try { + await client.close(); + } catch (cause) { + cleanupFailures.push(cause); + } + if (cleanupFailures.length > 0) { + process.stderr.write( + `Retained file-offset verifier workspace: ${workspace}\n`, + ); + throw new AggregateError( + primaryFailure === undefined + ? cleanupFailures + : [primaryFailure, ...cleanupFailures], + "File-offset verifier cleanup failed", + ); + } + if (complete) await rm(workspace, { recursive: true, force: true }); + else + process.stderr.write( + `Retained file-offset verifier workspace: ${workspace}\n`, + ); + } +} + +function assertMissingMappedProcedure(error, mappedAddress) { + assert.equal(error.code, "invalid_request"); + const message = error.details?.issues?.[0]?.message; + assert.equal(typeof message, "string"); + assert.ok( + message.includes("File offset 0x0 maps to analysis address"), + message, + ); + assert.ok(message.includes(mappedAddress), message); + assert.ok(message.includes("no procedure starts at or contains"), message); + assert.ok(!message.includes("--file-offset"), message); +} diff --git a/scripts/verify-package.mjs b/scripts/verify-package.mjs index fff3a07c6..32bad0a62 100644 --- a/scripts/verify-package.mjs +++ b/scripts/verify-package.mjs @@ -1,6 +1,8 @@ -import { mkdtemp, rm } from "node:fs/promises"; +import { mkdir, mkdtemp, rm, unlink } from "node:fs/promises"; +import { execFile } from "node:child_process"; import { tmpdir } from "node:os"; import { join } from "node:path"; +import { promisify } from "node:util"; import { TOOL_CONTRACTS } from "../dist/contracts/toolContracts.js"; import { PRODUCT_IDENTITY } from "../dist/identity.js"; @@ -21,12 +23,19 @@ import { verifyRepositorySkill } from "./verify-repository-skill.mjs"; import { verifyManaged } from "./verify-package-managed.mjs"; import { verifyUnknownProvider } from "./verify-package-unknown-provider.mjs"; import { completeVerifierRun, createVerifierRun } from "./lib/verifier-run.mjs"; +import { + createVerifiedPackageMetadata, + retainVerifiedPackage, + writeVerifiedPackageManifest, +} from "./ci/verified-package.mjs"; import { measureMcpStartup, profileMcpModuleLoading, } from "./lib/mcp-startup-probe.mjs"; const root = process.cwd(); +const execFileAsync = promisify(execFile); +const retentionDirectory = process.env.REA_VERIFIED_PACKAGE_DIRECTORY; const verifierRun = createVerifierRun(); const workspace = await mkdtemp(join(tmpdir(), "rea-package-")); const evidenceRoot = join(workspace, "evidence"); @@ -37,6 +46,8 @@ let mcpModuleLoading; let update; let repositorySkill; let report; +let retainedPackage; +let retentionMetadata; const runStage = async (name, action) => { const started = performance.now(); @@ -49,6 +60,27 @@ const runStage = async (name, action) => { }; try { + if (retentionDirectory !== undefined && retentionDirectory !== "") { + const sourceSha = ( + await execFileAsync("git", ["rev-parse", "HEAD"], { cwd: root }) + ).stdout.trim(); + retentionMetadata = createVerifiedPackageMetadata({ + sourceSha, + runId: process.env.GITHUB_RUN_ID, + runAttempt: process.env.GITHUB_RUN_ATTEMPT, + platform: process.platform, + architecture: process.arch, + packageVersion: PRODUCT_IDENTITY.packageVersion, + nodeVersion: process.version, + }); + await mkdir(retentionDirectory, { recursive: true }); + await unlink(join(retentionDirectory, "manifest.json")).catch((cause) => { + if ( + !(cause instanceof Error && "code" in cause && cause.code === "ENOENT") + ) + throw cause; + }); + } repositorySkill = await runStage("repository skill", () => verifyRepositorySkill({ root, workspace }), ); @@ -215,6 +247,13 @@ try { mcpStartup, mcpModuleLoading, }; + if (retentionMetadata !== undefined) { + retainedPackage = await retainVerifiedPackage({ + sourceTarball: tarball, + directory: retentionDirectory, + metadata: retentionMetadata, + }); + } } finally { await runStage("workspace cleanup", () => rm(workspace, { recursive: true, force: true }), @@ -223,6 +262,11 @@ try { const verifierLineage = await runStage("verifier lineage", () => completeVerifierRun(verifierRun), ); +if (retainedPackage !== undefined) + await writeVerifiedPackageManifest( + retainedPackage.directory, + retainedPackage.metadata, + ); process.stdout.write( `${JSON.stringify({ verifier_run: verifierLineage, ...report })}\n`, ); diff --git a/scripts/verify-real-ghidra-address-context.mjs b/scripts/verify-real-ghidra-address-context.mjs new file mode 100644 index 000000000..2b650df93 --- /dev/null +++ b/scripts/verify-real-ghidra-address-context.mjs @@ -0,0 +1,313 @@ +import assert from "node:assert/strict"; +import { execFile } from "node:child_process"; +import { createHash } from "node:crypto"; +import { mkdir, mkdtemp, readFile, readdir, rm } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { fileURLToPath } from "node:url"; +import { promisify } from "node:util"; +import { Client } from "@modelcontextprotocol/client"; +import { StdioClientTransport } from "@modelcontextprotocol/client/stdio"; +import { parseEvidence } from "../dist/domain/evidence.js"; +import { requireMcpOperationResult } from "./lib/mcp-verifier-results.mjs"; +import { createVerifierRun, completeVerifierRun } from "./lib/verifier-run.mjs"; + +if (process.argv.length !== 2 || process.platform !== "linux") + throw new Error("Run this ELF verifier on Linux without arguments."); +if (!process.env.GHIDRA_INSTALL_DIR) + throw new Error("Set GHIDRA_INSTALL_DIR to a caller-installed Ghidra."); +const exec = promisify(execFile); +const run = createVerifierRun(); +const root = fileURLToPath(new URL("..", import.meta.url)); +const workspace = await mkdtemp(join(tmpdir(), "rea-address-context-")); +const runtime = join(workspace, "runtime"); +await mkdir(runtime); +const path = join(workspace, "pie.elf"); +const entrypoint = join(root, "scripts/rea.mjs"); +const env = { + ...process.env, + TMPDIR: runtime, + REA_ANALYSIS_PROVIDER: "ghidra", + REA_LOG_LEVEL: "silent", +}; +const transport = new StdioClientTransport({ + command: process.execPath, + args: [entrypoint, "mcp"], + env, + stderr: "pipe", +}); +const client = new Client({ name: "rea-real-address-context", version: "1" }); +let stderr = ""; +transport.stderr?.on("data", (chunk) => { + stderr = (stderr + chunk.toString()).slice(-65536); +}); +let report; +let connected = false; +let primaryFailure; +let verifierRun; +try { + const compiler = process.env.CC ?? "gcc"; + const version = await exec(compiler, ["--version"], { timeout: 10000 }); + await exec( + compiler, + [ + "-O0", + "-g", + "-fPIE", + "-pie", + "-nostdlib", + "-Wl,-e,rea_pie_entry", + "-Wl,--build-id=none", + join(root, "tests/conformance/c/pie-address-context.c"), + "-o", + path, + ], + { timeout: 30000 }, + ); + const bytes = await readFile(path); + assert.equal(bytes.subarray(0, 6).toString("hex"), "7f454c460201"); + assert.equal(bytes.readUInt16LE(16), 3); // ET_DYN: source-owned x86-64 PIE. + assert.equal(bytes.readUInt16LE(18), 62); + const declaredEntry = `0x${bytes.readBigUInt64LE(24).toString(16)}`; + const sha256 = createHash("sha256").update(bytes).digest("hex"); + await client.connect(transport); + connected = true; + await call("open_binary", { path, provider_id: "ghidra" }); + const overview = parseEvidence(await call("binary_overview")); + assert.equal(overview.subject.digest.sha256, sha256); + const base = overview.normalized_result.image_base; + assert.match(base, /^0x[0-9a-f]+$/u); + assert.notEqual(base, "0x0"); + const active = await call("binary_session"); + const image = parseEvidence(await call("inspect_native_load_image")); + assert.equal(base, image.normalized_result.observations.image_base); + assert.ok(overview.normalized_result.segments.length > 0); + assert.ok( + overview.normalized_result.segments.every( + (segment) => + segment.image_base === base && + typeof segment.address_space === "string", + ), + ); + const procedures = parseEvidence(await call("list_procedures")); + const entry = procedures.normalized_result.find( + (item) => item.value === "rea_pie_entry", + ); + const addition = procedures.normalized_result.find( + (item) => item.value === "rea_pie_add", + ); + assert.ok(entry && addition); + assert.notEqual(entry.address, declaredEntry); + assert.ok( + image.normalized_result.observations.entry_points.includes(entry.address), + ); + const mapping = image.normalized_result.observations.mappings.find( + (item) => + item.source_file_index === 0 && + item.file_offset !== null && + item.address_space === "ram" && + BigInt(item.start) <= BigInt(entry.address) && + BigInt(item.end) >= BigInt(entry.address), + ); + assert.ok(mapping); + const offset = + mapping.file_offset + Number(BigInt(entry.address) - BigInt(mapping.start)); + const reverseMapping = parseEvidence( + await call("address_to_file_offset", { address: entry.address }), + ); + assert.equal(reverseMapping.normalized_result.file_offset, offset); + const memory = parseEvidence( + await call("read_bytes", { address: entry.address, length: 8 }), + ); + assert.equal( + memory.normalized_result.bytes_hex, + bytes.subarray(offset, offset + 8).toString("hex"), + ); + const fromOffset = parseEvidence( + await call("procedure_pseudo_code", { + procedure: `file-offset:0x${offset.toString(16)}`, + }), + ); + assert.ok( + fromOffset.locations.some( + (location) => + location.kind === "file-offset" && location.offset === offset, + ), + ); + assert.equal(fromOffset.raw_result.selection.mapped_address, entry.address); + const fromNumericOffset = parseEvidence( + await call("procedure_pseudo_code", { + procedure: `0x${offset.toString(16)}`, + }), + ); + assert.equal( + fromNumericOffset.normalized_result, + fromOffset.normalized_result, + ); + const missingAddress = "ram:0xffffffff"; + const rejected = await client.callTool( + { name: "procedure_pseudo_code", arguments: { procedure: missingAddress } }, + { timeout: 240000 }, + ); + assert.equal(rejected.isError, true); + assert.ok( + JSON.stringify(rejected.content).includes(`Ghidra image base: ${base}`), + ); + assert.ok(JSON.stringify(rejected.content).includes("list_procedures")); + assert.ok( + JSON.stringify(rejected.content).includes("inspect_native_load_image"), + ); + const pseudo = parseEvidence( + await call("procedure_pseudo_code", { procedure: addition.address }), + ); + assert.match(pseudo.normalized_result, /\+\s*(?:7|0x7)\b/u); + const retained = await call("binary_session"); + assert.equal(retained.analysis_run.run_id, active.analysis_run.run_id); + await call("close_binary"); + const cli = async (args) => + exec( + process.execPath, + [entrypoint, ...args, "--provider", "ghidra", "--json"], + { env, timeout: 240000, maxBuffer: 16 * 1024 * 1024 }, + ); + const cliOverview = parseEvidence( + JSON.parse((await cli(["analyze", path])).stdout), + ); + assert.deepEqual(cliOverview.normalized_result, overview.normalized_result); + let cliFailure; + try { + await cli(["decompile", path, missingAddress]); + } catch (cause) { + cliFailure = cause; + } + assert.ok(cliFailure && typeof cliFailure.stdout === "string"); + const error = JSON.parse(cliFailure.stdout); + assert.equal(error.code, "invalid_request"); + assert.ok(JSON.stringify(error).includes(`Ghidra image base: ${base}`)); + for (const command of [ + "rea search . --kind procedures --mode regex", + "rea analyze ", + "rea inspect-native-load-image ", + ]) + assert.ok(JSON.stringify(error).includes(command)); + const cliProcedures = parseEvidence( + JSON.parse( + ( + await cli([ + "search", + path, + ".", + "--kind", + "procedures", + "--mode", + "regex", + ]) + ).stdout, + ), + ); + const cliEntry = cliProcedures.normalized_result.find( + (item) => item.value === "rea_pie_entry", + ); + assert.ok(cliEntry); + assert.equal(cliEntry.address, entry.address); + const cliImage = parseEvidence( + JSON.parse((await cli(["inspect-native-load-image", path])).stdout), + ); + assert.equal(cliImage.normalized_result.observations.image_base, base); + const cliPseudo = parseEvidence( + JSON.parse((await cli(["decompile", path, cliEntry.address])).stdout), + ); + const cliOffset = parseEvidence( + JSON.parse( + (await cli(["decompile", path, `--file-offset=0x${offset.toString(16)}`])) + .stdout, + ), + ); + assert.equal(cliOffset.normalized_result, fromOffset.normalized_result); + assert.deepEqual(cliOffset.locations, fromOffset.locations); + assert.match(cliPseudo.normalized_result, /rea_pie_add/u); + assert.deepEqual(await readFile(path), bytes); + assert.deepEqual(await readdir(runtime), []); + report = { + ok: true, + mocked: false, + provider: image.provider, + compiler: version.stdout.split("\n")[0], + sha256, + declared_elf_entry: declaredEntry, + loaded_entry: entry.address, + observed_image_base: base, + cli_mcp_overview_parity: true, + failed_lookup_guidance: true, + cli_recovery_commands: true, + loaded_decompilation: true, + file_offset_decompilation: true, + address_file_offset_round_trip: true, + source_unchanged: true, + runtime_cleanup: "complete", + }; +} catch (cause) { + primaryFailure = { cause }; + if (stderr) process.stderr.write(stderr); +} + +const cleanupFailures = []; +// Await provider-owned cleanup before the SDK can terminate its MCP parent. +if (connected) { + try { + await call("close_binary"); + } catch (cause) { + cleanupFailures.push(cause); + } +} +try { + await client.close(); +} catch (cause) { + cleanupFailures.push(cause); +} +try { + await transport.close(); +} catch (cause) { + cleanupFailures.push(cause); +} +try { + assert.deepEqual(await readdir(runtime), []); + verifierRun = await completeVerifierRun(run); + assert.equal(verifierRun.process_lineage.status, "verified"); + assert.deepEqual(verifierRun.process_lineage.descendants, []); +} catch (cause) { + cleanupFailures.push(cause); +} +if (cleanupFailures.length === 0) { + try { + await rm(workspace, { recursive: true, force: true }); + } catch (cause) { + cleanupFailures.push(cause); + } +} +if (cleanupFailures.length > 0) { + process.stderr.write( + `Retained verifier workspace after cleanup failure: ${workspace}\n`, + ); + throw new AggregateError( + primaryFailure === undefined + ? cleanupFailures + : [primaryFailure.cause, ...cleanupFailures], + "Ghidra address-context verifier cleanup failed", + ); +} +if (primaryFailure !== undefined) throw primaryFailure.cause; +process.stdout.write( + JSON.stringify({ verifier_run: verifierRun, ...report }) + "\n", +); + +async function call(name, args = {}) { + const result = await client.callTool( + { name, arguments: args }, + { timeout: 240000 }, + ); + assert.notEqual(result.isError, true, JSON.stringify(result)); + return ["open_binary", "binary_session", "close_binary"].includes(name) + ? requireMcpOperationResult(result, name) + : result.structuredContent; +} diff --git a/scripts/verify-real-ghidra-windows.mjs b/scripts/verify-real-ghidra-windows.mjs index 5adf96009..bc822211f 100644 --- a/scripts/verify-real-ghidra-windows.mjs +++ b/scripts/verify-real-ghidra-windows.mjs @@ -28,6 +28,7 @@ import { import { parseBinaryTarget } from "../dist/application/BinaryTargetResolver.js"; import { completeVerifierRun, createVerifierRun } from "./lib/verifier-run.mjs"; import { verifyGhidraCompactReferences } from "./lib/real-ghidra-compact-references.mjs"; +import { verifyGhidraFileOffsets } from "./lib/real-ghidra-file-offsets.mjs"; const verifierRun = createVerifierRun(); const SESSION_CAPABILITIES = GHIDRA_SESSION_CAPABILITIES.filter( @@ -300,6 +301,11 @@ try { } if (report === undefined) throw new Error("Windows Ghidra report was not produced"); +report.file_offsets = await verifyGhidraFileOffsets( + targetPath, + resolve(root, "scripts", "rea.mjs"), + architecture === "x86" ? "0x401010" : "0x140001010", +); process.stdout.write( `${JSON.stringify({ verifier_run: await completeVerifierRun(verifierRun), ...report })}\n`, ); diff --git a/scripts/website.py b/scripts/website.py index 1d6661fc1..22c0829b9 100644 --- a/scripts/website.py +++ b/scripts/website.py @@ -114,7 +114,7 @@ def shared_blocks(root, path, source): } from website_i18n import language_markup selector, alternates = language_markup(root, path.relative_to(site).as_posix()) - values["language_picker"] = selector if not metadata.noindex else "" + values["language_picker"] = indent(selector, " ") if not metadata.noindex else "" values["alternates"] = alternates if not metadata.noindex else "" templates = root / "website/templates" return { diff --git a/src/application/EnhancedTools.ts b/src/application/EnhancedTools.ts index c8b80519f..87d27fc5f 100644 --- a/src/application/EnhancedTools.ts +++ b/src/application/EnhancedTools.ts @@ -21,8 +21,8 @@ import { parseFunctionDossier, parseListCount, parseRelatedAddresses, - parseSegmentImageBase, parseSegments, + parseSegmentImageBase, } from "../domain/hopperValues.js"; import { err, ok, type Result } from "../domain/result.js"; import { @@ -46,6 +46,7 @@ import { traceCallPath } from "./CallPathTracing.js"; import { resolveProcedureAddress } from "./ProcedureAddressResolution.js"; import { traceLiteralFeature } from "./EnhancedLiteralTracing.js"; import { projectNativeApiInspection } from "./native/NativeApiInspection.js"; + /** * Composes direct provider operations into bounded reverse-engineering tools. * Direct callers use `execute`; adapters that own validation use @@ -528,24 +529,29 @@ export class EnhancedTools { const segments = parseSegments(segmentsResult.value); if (!segments.ok) return segments; - const imageBase = parseSegmentImageBase(segmentsResult.value); const procedureCount = parseListCount(proceduresResult.value, "procedures"); if (!procedureCount.ok) return procedureCount; const stringCount = parseListCount(stringsResult.value, "strings"); if (!stringCount.ok) return stringCount; + const imageBase = parseSegmentImageBase(segments.value); + return ok({ document: document.value, - segments: segments.value.map(({ name, start, end }) => ({ - name, - start, - end, - length: addressDistance(start, end), - })), + ...(imageBase === undefined ? {} : { image_base: imageBase }), + segments: segments.value.map( + ({ name, start, end, image_base, address_space }) => ({ + name, + start, + end, + length: addressDistance(start, end), + ...(image_base === undefined ? {} : { image_base }), + ...(address_space === undefined ? {} : { address_space }), + }), + ), segment_count: segments.value.length, procedure_count: procedureCount.value, string_count: stringCount.value, - ...(imageBase === undefined ? {} : { image_base: imageBase }), }); } diff --git a/src/application/InvestigationProviders.ts b/src/application/InvestigationProviders.ts index 883d3878c..5dcb18150 100644 --- a/src/application/InvestigationProviders.ts +++ b/src/application/InvestigationProviders.ts @@ -18,11 +18,11 @@ export const workflowAnalysisProfile = ( ): AnalysisProfileCommitment => createAnalysisProfile(REA_WORKFLOW_PROVIDER, { upstream_analysis_profile: upstream, - ...(operation === "binary_overview" || - operation === "batch_decompile" || - operation === "get_call_graph" - ? { workflow_revision: 2 } - : {}), + ...(operation === "binary_overview" + ? { workflow_revision: 3 } + : operation === "batch_decompile" || operation === "get_call_graph" + ? { workflow_revision: 2 } + : {}), }); /** Provider identity for deterministic artifact inventories. */ diff --git a/src/artifacts/MachOSliceArtifactReader.ts b/src/artifacts/MachOSliceArtifactReader.ts index 5928956ee..f567458c7 100644 --- a/src/artifacts/MachOSliceArtifactReader.ts +++ b/src/artifacts/MachOSliceArtifactReader.ts @@ -8,11 +8,11 @@ import { type NativeCommandRunner, } from "../native/CommandRunner.js"; import { - lipoSubtypeBits, parseLipoArchitectures, type LipoArchitecture, } from "../native/parsers/lipo.js"; import type { MachoSlice } from "../domain/apple/dylibResolution.js"; +import { machoCpuSubtypeBase } from "../domain/apple/machoCpuIdentity.js"; import { OwnedFileHandle } from "../filesystem/OwnedFileHandle.js"; import { readMachoImage, type ReadAt } from "./apple/MachoLoadCommandReader.js"; import { @@ -471,8 +471,10 @@ const lipoSubtypeMatches = ( ): boolean => { if (reported.cpu_subtype_code !== null) return reported.cpu_subtype_code === observedCpuSubtype; - const bits = lipoSubtypeBits(reported.cpu_subtype); - return bits === null || bits === (observedCpuSubtype & 0x00ffffff); + return ( + reported.cpu_subtype_base === null || + reported.cpu_subtype_base === machoCpuSubtypeBase(observedCpuSubtype) + ); }; /** diff --git a/src/artifacts/SafeOutputTree.ts b/src/artifacts/SafeOutputTree.ts index 8fa40876d..73885ad05 100644 --- a/src/artifacts/SafeOutputTree.ts +++ b/src/artifacts/SafeOutputTree.ts @@ -585,6 +585,11 @@ const normalizeDestinationPath = ( "path", `Windows destination cannot materialize artifact path as a regular file: ${path}; ':' denotes alternate data stream syntax.`, ); + if (platform === "win32" && /[\u0001-\u001f]/u.test(path)) + throw new ArtifactReaderFailure( + "path", + `Windows destination cannot materialize artifact path: ${JSON.stringify(path)}; Windows names cannot contain U+0001-U+001F.`, + ); return path; }; diff --git a/src/artifacts/ZipArtifactReader.ts b/src/artifacts/ZipArtifactReader.ts index 11c68557b..dfbee8b27 100644 --- a/src/artifacts/ZipArtifactReader.ts +++ b/src/artifacts/ZipArtifactReader.ts @@ -255,10 +255,29 @@ const decodeZipEntryText = ( encoding: string, type: "filename" | "comment", ): string | undefined => { - if (type !== "filename" || encoding !== "utf-8") return undefined; - return decodeStrictZipUtf8(bytes, "ZIP filename is not valid UTF-8"); + if (type !== "filename") return undefined; + if (encoding === "utf-8") + return decodeStrictZipUtf8(bytes, "ZIP filename is not valid UTF-8"); + return encoding === "cp437" ? decodeCp437(bytes) : undefined; }; +/** CP437 characters for bytes 0x80-0xFF. */ +const CP437_HIGH_HALF = + "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■\u00A0"; + +/** + * Decode a legacy ZIP name with the Unicode CP437 mapping, which Python's + * zipfile also uses: bytes below 0x80 are ASCII. zip.js shows 0x01-0x1F and + * 0x7F as IBM PC display glyphs, which turns the macOS folder icon file + * `Icon\r` into `Icon♪`. + */ +const decodeCp437 = (bytes: Uint8Array): string => + Array.from(bytes, (byte) => + byte < 0x80 + ? String.fromCharCode(byte) + : CP437_HIGH_HALF.charAt(byte - 0x80), + ).join(""); + const zipEntryPath = (entry: Entry): string => { const field = entry.extraFieldUnicodePath; if (field?.valid !== true) return entry.filename; diff --git a/src/artifacts/apple/NibArchive.ts b/src/artifacts/apple/NibArchive.ts index bd8ef12ca..c673184f4 100644 --- a/src/artifacts/apple/NibArchive.ts +++ b/src/artifacts/apple/NibArchive.ts @@ -134,7 +134,14 @@ export const decodeNibArchive = ( const value = values.get(index); if (value === undefined) continue; const key = keys[value.key_index]; - if (key !== undefined) fields[key] = value.value; + if (key !== undefined) + // Archive keys are data, including the legacy __proto__ setter name. + Object.defineProperty(fields, key, { + value: value.value, + enumerable: true, + configurable: true, + writable: true, + }); } return [{ id, class_name: className, values: fields }]; }); @@ -519,7 +526,8 @@ const decodeUtf8 = ( label: string, ): string => { try { - return new TextDecoder("utf-8", { fatal: true }).decode( + // These are length-prefixed names, not standalone text documents. + return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode( bytes.subarray(start, end), ); } catch (cause: unknown) { diff --git a/src/browser/history/HarCapture.test.ts b/src/browser/history/HarCapture.test.ts index 9614384cc..b931fda06 100644 --- a/src/browser/history/HarCapture.test.ts +++ b/src/browser/history/HarCapture.test.ts @@ -162,6 +162,19 @@ it("rejects identical duplicate core fields before schema validation", () => { expect(() => decodeHarCapture(text, [])).toThrow("duplicate"); }); +it("names the violated HAR schema constraint without restating capture values", () => { + expect(() => + decodeHarCapture( + JSON.stringify({ + log: { creator: { name: "x", version: "1" }, entries: [] }, + }), + [], + ), + ).toThrow( + "HAR schema validation failed: required (must have required property 'version').", + ); +}); + it("preserves prototype-named producer members through the capture boundary", () => { const text = JSON.stringify(historicalHar()).replace( '"cache":{}', diff --git a/src/browser/history/HarSchema.ts b/src/browser/history/HarSchema.ts index 069377f8a..add8c301e 100644 --- a/src/browser/history/HarSchema.ts +++ b/src/browser/history/HarSchema.ts @@ -23,9 +23,13 @@ export const createHarValidator = (): ((value: unknown) => void) => { allowMitmproxyAbsentPostData(value); if (!validate(value)) { const error = validate.errors?.[0]; + // AJV messages name the violated constraint, such as the missing + // property, without restating any captured value. throw new CaptureFormatError( "format", - `HAR schema validation failed: ${error?.keyword ?? "unknown constraint"}.`, + error === undefined + ? "HAR schema validation failed: unknown constraint." + : `HAR schema validation failed: ${error.keyword} (${error.message ?? "no detail"}).`, error?.instancePath ?? "", ); } diff --git a/src/cli/apktoolCommands.ts b/src/cli/apktoolCommands.ts index d7b30a617..c7795f9d4 100644 --- a/src/cli/apktoolCommands.ts +++ b/src/cli/apktoolCommands.ts @@ -62,15 +62,17 @@ export const registerApktoolCommands = ( .describe( "Project strings from res/values- instead of the default", ), - "no-strings": z + strings: z .boolean() - .default(false) - .describe("Skip projecting string resources"), + .default(true) + .describe( + "Include string resources; use --no-strings to skip projecting them", + ), }), run: ({ args, options }) => execute(CLI_COMMANDS.decodeAndroidResources, "decode_android_resources", { path: args.path, - include_strings: !options["no-strings"], + include_strings: options.strings, ...(options.locale === undefined ? {} : { locale: options.locale }), }), }); diff --git a/src/cli/coreBinaryCommands.ts b/src/cli/coreBinaryCommands.ts index 70405302e..710b39181 100644 --- a/src/cli/coreBinaryCommands.ts +++ b/src/cli/coreBinaryCommands.ts @@ -137,6 +137,13 @@ const registerDecompileCommand = ( .describe( "Procedure name or address; use --procedure= for leading dashes", ), + "file-offset": z + .string() + .regex(/^0x[0-9a-fA-F]+$/u) + .optional() + .describe( + "Ghidra source-file byte offset; mapped internally to an analysis address", + ), snapshot: z .string() .min(1) @@ -152,8 +159,17 @@ const registerDecompileCommand = ( { procedure: resolveCliAnalysisSelector( args.address, - options.procedure, - "procedure", + options["file-offset"] === undefined + ? options.procedure + : resolveCliAnalysisSelector( + options.procedure, + `file-offset:${options["file-offset"]}`, + "file-offset", + "procedure_pseudo_code", + ), + options["file-offset"] === undefined + ? "procedure" + : "file-offset", "procedure_pseudo_code", ), }, diff --git a/src/contracts/officialToolContracts.ts b/src/contracts/officialToolContracts.ts index f9c024fe5..82f1dc83d 100644 --- a/src/contracts/officialToolContracts.ts +++ b/src/contracts/officialToolContracts.ts @@ -181,7 +181,7 @@ export const OFFICIAL_TOOL_CONTRACTS = [ ), official( "procedure_pseudo_code", - "Decompile one analyzed procedure by symbol name or provider-normalized address. Returns provider-specific pseudocode, never original source or cross-provider text equivalence, and may return null; request procedure_assembly when instruction precision matters. Ghidra no-return assumptions may cut the analyzed body; Evidence limitations report observed terminal calls and available callee identities.", + "Decompile one analyzed procedure by symbol name or provider-normalized address. Ghidra also accepts file-offset:0x... selectors and falls back to a unique source-file mapping when a 0x-prefixed number resolves to no procedure; existing analysis addresses take precedence and ambiguous mappings fail explicitly. Returns provider-specific pseudocode, never original source or cross-provider text equivalence, and may return null; request procedure_assembly when instruction precision matters. Ghidra no-return assumptions may cut the analyzed body; Evidence limitations report observed terminal calls and available callee identities.", z.object({ procedure, document }), ), official( diff --git a/src/contracts/toolOutputSchemaGroups.ts b/src/contracts/toolOutputSchemaGroups.ts index 174339bdf..dcf7ad033 100644 --- a/src/contracts/toolOutputSchemaGroups.ts +++ b/src/contracts/toolOutputSchemaGroups.ts @@ -357,18 +357,20 @@ export const enhancedOutputSchemas: Readonly> = { binary_overview: evidenceResultOf( z.object({ document: z.string(), + image_base: z.string().min(1).optional(), segments: z.array( z.object({ name: z.string(), start: z.string(), end: z.string(), length: z.number().min(0), + image_base: z.string().exactOptional(), + address_space: z.string().exactOptional(), }), ), segment_count: z.number().int().min(0), procedure_count: z.number().int().min(0), string_count: z.number().int().min(0), - image_base: z.string().min(1).optional(), }), ), analyze_function: functionDossierOutput, diff --git a/src/domain/apple/dylibResolution.ts b/src/domain/apple/dylibResolution.ts index 799befdb1..cf10c4b78 100644 --- a/src/domain/apple/dylibResolution.ts +++ b/src/domain/apple/dylibResolution.ts @@ -16,6 +16,7 @@ import { import { DYLIB_RESOLUTION_LIMITATIONS, deriveFindings, + type TracedRootSlice, } from "./dylibResolutionFindings.js"; /** @@ -568,6 +569,7 @@ export const traceDylibLoading = async ( for (const path of request.unclassified ?? []) images.set(path, await view.image(path)); const roots: DylibTrace["roots"][number][] = []; + const rootSlices: TracedRootSlice[] = []; const edges: Edge[] = []; const withoutArchitecture: string[] = []; const environmentRoots = new Set(); @@ -597,6 +599,7 @@ export const traceDylibLoading = async ( ) environmentRoots.add(root); roots.push({ image: root, architecture: slice.architecture }); + rootSlices.push({ image: root, slice }); edges.push( ...(await traceProcess( { @@ -641,7 +644,7 @@ export const traceDylibLoading = async ( facts.status === "parsed" ? facts.slices.map(withoutDependencies) : [], })), edges, - findings: deriveFindings(edges, roots, images), + findings: deriveFindings(edges, rootSlices), coverage: { status: unparsed.length === 0 && diff --git a/src/domain/apple/dylibResolutionFindings.ts b/src/domain/apple/dylibResolutionFindings.ts index ca506c17b..eac488143 100644 --- a/src/domain/apple/dylibResolutionFindings.ts +++ b/src/domain/apple/dylibResolutionFindings.ts @@ -1,14 +1,18 @@ import type { DylibEdge as Edge, DylibFinding as Finding, - DylibTrace, - MachoImageFacts, + MachoSlice, } from "./dylibResolution.js"; +/** One traced process root with the exact slice it was traced from. */ +export interface TracedRootSlice { + readonly image: string; + readonly slice: MachoSlice; +} + export const deriveFindings = ( edges: readonly Edge[], - roots: DylibTrace["roots"], - images: ReadonlyMap, + roots: readonly TracedRootSlice[], ): Finding[] => { const findings: Finding[] = []; edges.forEach((edge, index) => { @@ -32,15 +36,11 @@ export const deriveFindings = ( explanation: `The modeled dyld search checks ${earlier.join(", ")} before ${edge.resolution.image ?? edge.install_name}. A compatible Mach-O placed at an earlier modeled path could take precedence over that fallback, subject to unmodeled search inputs and code-signing library validation; library validation is not evaluated here (see inspect_signature).${edge.loader_conditional ? " This loader loads only conditionally; if it never loads, this search never occurs." : ""}${edge.resolution.status === "conditional" ? " Unmodeled environment overrides or earlier unknown candidates may take precedence; placing an image at this rpath does not establish which image dyld will load." : ""}`, }); }); - for (const { image, architecture } of roots) { - const facts = images.get(image); - const slice = - facts?.status === "parsed" - ? facts.slices.find( - (candidate) => candidate.architecture === architecture, - ) - : undefined; - const environment = slice?.dyld_environment ?? []; + // Slices can share an architecture name (arm64e and arm64e.x1), so each + // finding uses the slice its root was traced from, not a name lookup. + for (const { image, slice } of roots) { + const { architecture } = slice; + const environment = slice.dyld_environment; if (environment.length > 0) findings.push({ kind: "dyld-environment-present", @@ -48,7 +48,7 @@ export const deriveFindings = ( image, basis: "derived", explanation: - slice?.file_type === "execute" + slice.file_type === "execute" ? `${image} (${architecture}) sets dyld environment variables through LC_DYLD_ENVIRONMENT (${environment.join(", ")}); any image-selection overrides they request are not modeled. Diagnostic settings alone do not alter resolution.` : `${image} (${architecture}) contains LC_DYLD_ENVIRONMENT (${environment.join(", ")}). Dyld reads these commands only from the main executable; entries in this non-executable root are observations and do not alter resolution.`, }); diff --git a/src/domain/hopperValues.test.ts b/src/domain/hopperValues.test.ts index 7af5df704..c5931cd35 100644 --- a/src/domain/hopperValues.test.ts +++ b/src/domain/hopperValues.test.ts @@ -8,7 +8,6 @@ import { parseNames, parseProcedures, parseRelatedAddresses, - parseSegmentImageBase, parseSegments, } from "./hopperValues.js"; @@ -66,19 +65,6 @@ describe("Hopper boundary values", () => { ok: true, value: ["fixture"], }); - expect( - parseSegmentImageBase([ - { image_base: "0x100000" }, - { image_base: "0x100000" }, - ]), - ).toBe("0x100000"); - expect( - parseSegmentImageBase([ - { image_base: "0x100000" }, - { image_base: "0x200000" }, - ]), - ).toBeUndefined(); - expect(parseSegmentImageBase([{ name: "__TEXT" }])).toBeUndefined(); }); it.each([ diff --git a/src/domain/hopperValues.ts b/src/domain/hopperValues.ts index 5e5a3987b..769d0f040 100644 --- a/src/domain/hopperValues.ts +++ b/src/domain/hopperValues.ts @@ -20,6 +20,8 @@ export interface SegmentSummary { readonly readable: boolean | null; readonly writable: boolean | null; readonly executable: boolean | null; + readonly image_base?: string; + readonly address_space?: string; } /** Return a bounded byte distance between canonical addresses in one space. */ @@ -58,10 +60,9 @@ const segmentSchema = z.object({ readable: z.boolean().nullable(), writable: z.boolean().nullable(), executable: z.boolean().nullable(), + image_base: z.string().min(1).exactOptional(), + address_space: z.string().min(1).exactOptional(), }); -const segmentImageBaseSchema = z - .object({ image_base: z.string().min(1) }) - .passthrough(); const unavailableAnalysisFactSchema = z .object({ available: z.literal(false), reason: z.string() }) .strict(); @@ -415,7 +416,7 @@ export const parseRelatedAddresses = ( : invalid(`${relation} list`, parsed.error); }; -/** Parse direct or wrapped Hopper segment records. */ +/** Preserve reported address context in direct or wrapped provider segments. */ export const parseSegments = ( value: JsonValue, ): Result => { @@ -427,14 +428,15 @@ export const parseSegments = ( : invalid("segment list", parsed.error); }; -/** Return a provider-reported image base only when every segment agrees on it. */ -export const parseSegmentImageBase = (value: JsonValue): string | undefined => { - const parsed = z - .array(segmentImageBaseSchema) - .safeParse(unwrapProperty(value, "segments")); - if (!parsed.success) return undefined; - const bases = new Set(parsed.data.map(({ image_base }) => image_base)); - return bases.size === 1 ? parsed.data[0]?.image_base : undefined; +/** Return a reported overview base only when every parsed segment agrees. */ +export const parseSegmentImageBase = ( + segments: readonly SegmentSummary[], +): string | undefined => { + const base = segments[0]?.image_base; + return base !== undefined && + segments.every((segment) => segment.image_base === base) + ? base + : undefined; }; /** Parse direct or wrapped Hopper document names. */ diff --git a/src/domain/javascript/javascriptBundlerRegistrationIdentity.test.ts b/src/domain/javascript/javascriptBundlerRegistrationIdentity.test.ts new file mode 100644 index 000000000..1b251e313 --- /dev/null +++ b/src/domain/javascript/javascriptBundlerRegistrationIdentity.test.ts @@ -0,0 +1,78 @@ +import { expect, it } from "vitest"; +import { analyzeJavaScriptStaticSource } from "./javascriptStaticAnalysis.js"; + +const registration = (runtime: string, callback: string, chunk = 1) => + "(globalThis." + + runtime + + " = globalThis." + + runtime + + " || []).push([[" + + chunk + + "], {a: function() {}}, " + + callback + + "]);"; + +it.each(["webpackChunkFixture", "rspackChunkFixture"])( + "keeps differing callback facts for %s independent of source order", + (runtime) => { + const first = registration( + runtime, + 'function(r) { r(7); r.e("chunk-a"); }', + ); + const second = registration( + runtime, + 'function(r) { r(8); r.e("chunk-b"); }', + ); + for (const source of [first + "\n" + second, second + "\n" + first]) { + const result = analyzeJavaScriptStaticSource(source); + expect(result.parse_status).toBe("complete"); + expect(result.bundler_registrations).toHaveLength(2); + expect( + result.bundler_registrations.flatMap((r) => r.entry_module_keys).sort(), + ).toEqual(["7", "8"]); + expect( + result.bundler_registrations.flatMap((r) => r.async_chunk_keys).sort(), + ).toEqual(["chunk-a", "chunk-b"]); + } + expect( + analyzeJavaScriptStaticSource(first + "\n" + first).bundler_registrations, + ).toHaveLength(1); + expect( + analyzeJavaScriptStaticSource(first).bundler_registrations[0], + ).toMatchObject({ + entry_module_keys: ["7"], + async_chunk_keys: ["chunk-a"], + }); + expect( + analyzeJavaScriptStaticSource(second).bundler_registrations[0], + ).toMatchObject({ + entry_module_keys: ["8"], + async_chunk_keys: ["chunk-b"], + }); + }, +); + +it.each([ + ["function(r) { r(7); }", "function(r) { r(8); }"], + ['function(r) { r.e("a"); }', 'function(r) { r.e("b"); }'], + ["function(r) {}", "function(s) {}"], + ["function(r) {}", "function(r) { r(dynamic); }"], + ["function(r) {}", "function(r) { r.e(dynamic); }"], +])("retains callback metadata differences: %s / %s", (left, right) => { + const result = analyzeJavaScriptStaticSource( + registration("webpackChunkFixture", left) + + "\n" + + registration("webpackChunkFixture", right), + ); + expect(result.bundler_registrations).toHaveLength(2); +}); + +it("retains distinct chunk identities with identical callbacks", () => { + const callback = "function(r) { r(7); }"; + const result = analyzeJavaScriptStaticSource( + registration("webpackChunkFixture", callback, 1) + + "\n" + + registration("webpackChunkFixture", callback, 2), + ); + expect(result.bundler_registrations).toHaveLength(2); +}); diff --git a/src/domain/javascript/javascriptStaticAnalysisHelpers.ts b/src/domain/javascript/javascriptStaticAnalysisHelpers.ts index a6a6ebc44..71562e6ca 100644 --- a/src/domain/javascript/javascriptStaticAnalysisHelpers.ts +++ b/src/domain/javascript/javascriptStaticAnalysisHelpers.ts @@ -691,6 +691,14 @@ export const registrationKey = ( registration.runtime, registration.chunk_keys, String(registration.unknown_chunk_keys), + // Equal factory tables can be registered with different runtime callbacks. + // Both early collection and finalization must retain those recovered facts. + registration.runtime_require_name, + registration.runtime_module_cache_status, + registration.entry_module_keys, + String(registration.unknown_entry_module_keys), + registration.async_chunk_keys, + String(registration.unknown_async_chunk_keys), registration.modules.map(({ module_key: key, source_sha256: digest }) => [ key, digest, diff --git a/src/dotnet/ManagedMemberInstructionDecoder.ts b/src/dotnet/ManagedMemberInstructionDecoder.ts index f638e3e83..7ef518733 100644 --- a/src/dotnet/ManagedMemberInstructionDecoder.ts +++ b/src/dotnet/ManagedMemberInstructionDecoder.ts @@ -265,6 +265,10 @@ type OperandResult = { type OperandReader = (il: Buffer, offset: number) => OperandResult; +// String(-0) loses a CIL constant's sign in both anchors and normalized hashes. +const floatingPointOperand = (value: number): string => + Object.is(value, -0) ? "-0" : String(value); + const FIXED_OPERAND_READERS = new Map([ [ "none", @@ -315,7 +319,7 @@ const FIXED_OPERAND_READERS = new Map([ (il, offset) => ({ next: offset + 4, anchorKind: "constant", - value: String(il.readFloatLE(offset)), + value: floatingPointOperand(il.readFloatLE(offset)), }), ], [ @@ -323,7 +327,7 @@ const FIXED_OPERAND_READERS = new Map([ (il, offset) => ({ next: offset + 8, anchorKind: "constant", - value: String(il.readDoubleLE(offset)), + value: floatingPointOperand(il.readDoubleLE(offset)), }), ], [ diff --git a/src/ghidra/GhidraAnalysisProfile.ts b/src/ghidra/GhidraAnalysisProfile.ts index 60edb0971..fd7cdff11 100644 --- a/src/ghidra/GhidraAnalysisProfile.ts +++ b/src/ghidra/GhidraAnalysisProfile.ts @@ -123,6 +123,8 @@ export const resolveGhidraAnalysisProfile = async ( call_relationship_coverage: "resolved-call-reference-diagnostics-v1", string_inventory_evidence: "defined-data-coverage-v1", location_resolution: "explicit-address-exact-entry-symbol-first-v3", + procedure_file_offset_resolution: + "address-first-unique-target-source-mapping-v2", instruction_flow_evidence: "decoded-return-pcode-v1", instruction_references: "exact-address-incoming-v1", function_boundary_observations: "ghidra-terminal-call-limitations-v1", @@ -212,6 +214,8 @@ export const resolveGhidraAnalysisProfile = async ( call_relationship_coverage: "resolved-call-reference-diagnostics-v1", string_inventory_evidence: "defined-data-coverage-v1", location_resolution: "explicit-address-exact-entry-symbol-first-v3", + procedure_file_offset_resolution: + "address-first-unique-target-source-mapping-v2", instruction_flow_evidence: "decoded-return-pcode-v1", instruction_references: "exact-address-incoming-v1", function_boundary_observations: "ghidra-terminal-call-limitations-v1", diff --git a/src/ghidra/GhidraDoctor.test.ts b/src/ghidra/GhidraDoctor.test.ts index e5d20f4c8..69b9acb62 100644 --- a/src/ghidra/GhidraDoctor.test.ts +++ b/src/ghidra/GhidraDoctor.test.ts @@ -1,9 +1,10 @@ -import { describe, expect, it } from "vitest"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { runDoctor, type DoctorHost } from "../application/Doctor.js"; import { createDoctorHostFixture } from "../application/Doctor.fixture.js"; import { providerRegistrationEnvironment } from "../application/SetupRegistrationEnvironment.js"; import { WINDOWS_NATIVE_AUTHORITY_UNAVAILABLE_REASON } from "../process/WindowsAuthority.js"; +import * as windowsAuthority from "../process/WindowsAuthority.js"; import { inspectGhidraInstallation, type GhidraInstallationHost, @@ -173,6 +174,16 @@ describe("Ghidra doctor integration", () => { }); describe("Windows Ghidra doctor authority", () => { + beforeEach(() => { + vi.spyOn(windowsAuthority, "hasWindowsNativeAuthority").mockReturnValue( + false, + ); + vi.spyOn( + windowsAuthority, + "windowsNativeAuthorityUnavailableReason", + ).mockReturnValue(WINDOWS_NATIVE_AUTHORITY_UNAVAILABLE_REASON); + }); + afterEach(() => vi.restoreAllMocks()); it("distinguishes a valid Windows installation from unavailable native authority", async () => { const ghidra = inspection({ installDir: "C:\\tools\\ghidra_12.1.4_PUBLIC", diff --git a/src/ghidra/GhidraFunctionValues.test.ts b/src/ghidra/GhidraFunctionValues.test.ts index 662db0a26..75d59c97f 100644 --- a/src/ghidra/GhidraFunctionValues.test.ts +++ b/src/ghidra/GhidraFunctionValues.test.ts @@ -42,6 +42,30 @@ const parseFunctionValueFixture = ( }; describe("Ghidra function-analysis result values", () => { + it("preserves file-offset resolution in Evidence locations and rejects inexact offsets", () => { + const selection = { + file_offset: 0x210, + mapped_address: "0x140001010", + procedure_address: "0x140001010", + }; + const wire = { value: "return 42;", limitations: [], selection }; + expect(parseGhidraFunctionResult("procedure_assembly", wire)).toMatchObject( + { ok: false, error: { _tag: "AnalysisOutputError" } }, + ); + const parsed = parseGhidraFunctionResult("procedure_pseudo_code", wire); + if (!parsed.ok) throw parsed.error; + expect(parsed.value.locations).toEqual([ + { kind: "file-offset", offset: 0x210 }, + { kind: "address", address: "0x140001010" }, + { kind: "address", address: "0x140001010" }, + ]); + expect( + parseGhidraFunctionResult("procedure_pseudo_code", { + ...wire, + selection: { ...selection, file_offset: Number.MAX_SAFE_INTEGER + 1 }, + }), + ).toMatchObject({ ok: false, error: { _tag: "AnalysisOutputError" } }); + }); it.each([...observationOperations])( "requires the function-observation limitations envelope for %s", (operation) => { diff --git a/src/ghidra/GhidraFunctionValues.ts b/src/ghidra/GhidraFunctionValues.ts index 8876e31ae..d45e41ba9 100644 --- a/src/ghidra/GhidraFunctionValues.ts +++ b/src/ghidra/GhidraFunctionValues.ts @@ -26,6 +26,7 @@ import { } from "../domain/jsonValue.js"; import { nativeApiBoundarySchema } from "../domain/native/nativeApiBoundary.js"; import { nativeValueFlowSchema } from "../domain/native/nativeValueFlow.js"; +import type { EvidenceLocation } from "../domain/evidence.js"; import { err, ok, type Result } from "../domain/result.js"; import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js"; import { @@ -399,11 +400,19 @@ const functionBoundaryObservationOperations: ReadonlySet["selection"]; }; if (functionBoundaryObservationOperations.has(operation)) { const envelope = functionObservationEnvelope.safeParse(value); - if (!envelope.success) + if ( + !envelope.success || + (operation !== "procedure_pseudo_code" && + envelope.data.selection !== undefined) + ) return err( new AnalysisOutputError( operation, "Ghidra bridge omitted the function observation envelope", - { cause: envelope.error }, + envelope.success ? undefined : { cause: envelope.error }, ), ); observation = envelope.data; @@ -434,6 +450,24 @@ export const parseGhidraFunctionResult = ( ? ok({ value: jsonValueSchema.parse(parsed.data), limitations: observation.limitations, + ...(observation.selection === undefined + ? {} + : { + locations: [ + { + kind: "file-offset" as const, + offset: observation.selection.file_offset, + }, + { + kind: "address" as const, + address: observation.selection.mapped_address, + }, + { + kind: "address" as const, + address: observation.selection.procedure_address, + }, + ], + }), }) : err( new AnalysisOutputError( diff --git a/src/ghidra/GhidraProviderClient.ts b/src/ghidra/GhidraProviderClient.ts index 5a4f4eafd..5911985df 100644 --- a/src/ghidra/GhidraProviderClient.ts +++ b/src/ghidra/GhidraProviderClient.ts @@ -32,6 +32,7 @@ import { AnalysisTimeoutError, } from "../domain/analysisErrorCore.js"; import type { AnalysisError } from "../domain/analysisErrorBase.js"; +import type { EvidenceLocation } from "../domain/evidence.js"; import { jsonValueSchema, type JsonValue } from "../domain/jsonValue.js"; import { ProviderAdapterError } from "../domain/providerAdapterError.js"; import { err, ok, type Result } from "../domain/result.js"; @@ -678,10 +679,12 @@ export const createGhidraProviderClient = (input: { normalized: JsonValue, rawResult: JsonValue, observationLimitations: readonly string[] = [], + locations: readonly EvidenceLocation[] = [], ) => { const relationshipCoverage = relationshipCoverageFor(operation); return createAnalysisExecution(normalized, committedProfile.provider, { rawResult, + locations, analysisProfile: committedProfile, ...(relationshipCoverage === undefined ? {} : { relationshipCoverage }), limitations: [ @@ -776,11 +779,13 @@ export const createGhidraProviderClient = (input: { ); let normalized: JsonValue; let observationLimitations: readonly string[] = []; + let observationLocations: readonly EvidenceLocation[] = []; if (isGhidraFunctionOperation(operation)) { const result = parseGhidraFunctionResult(operation, called.value); if (!result.ok) return result; normalized = result.value.value; observationLimitations = result.value.limitations; + observationLocations = result.value.locations ?? []; } else { const result = parseGhidraInventoryResult(operation, called.value); if (!result.ok) return result; @@ -875,6 +880,7 @@ export const createGhidraProviderClient = (input: { normalized, called.value, observationLimitations, + observationLocations, ), ); }, diff --git a/src/native/AppleMachoSelection.test.ts b/src/native/AppleMachoSelection.test.ts index 5c19026e0..af2d0be55 100644 --- a/src/native/AppleMachoSelection.test.ts +++ b/src/native/AppleMachoSelection.test.ts @@ -7,9 +7,13 @@ import { fatImage, machoImage, } from "../artifacts/apple/MachoImage.fixture.js"; -import { parseMachoLayout } from "./AppleMachoSelection.js"; +import { parseMachoLayout, selectMachoSlice } from "./AppleMachoSelection.js"; import { decodeAppleDispatchMetadata } from "./AppleDispatchMetadata.js"; +/** macOS 27 system binaries ship CPU_SUBTYPE_ARM64E_X1 (12) with the PAC ABI bit. */ +const ARM64E_X1 = { type: 0x0100000c, subtype: 0x8000000c } as const; +const X86_64H = { type: 0x01000007, subtype: 8 } as const; + describe("native Mach-O slice selection", () => { it("preserves high-bit section-name bytes instead of ASCII-folding metadata names", () => { const segment = Buffer.alloc(152); @@ -68,6 +72,48 @@ describe("native Mach-O slice selection", () => { /not aligned/u, ); }); + + it.each([ + { layout: "arm64e, arm64e.x1", cpus: [CPU.arm64e, ARM64E_X1], index: 0 }, + { layout: "arm64e.x1, arm64e", cpus: [ARM64E_X1, CPU.arm64e], index: 1 }, + { layout: "arm64, arm64e.x1", cpus: [CPU.arm64, ARM64E_X1], index: 0 }, + { layout: "arm64e.x1, arm64", cpus: [ARM64E_X1, CPU.arm64], index: 1 }, + { + layout: "x86_64, arm64e, arm64e.x1", + cpus: [CPU.x86_64, CPU.arm64e, ARM64E_X1], + index: 1, + }, + { + layout: "x86_64h, x86_64", + cpus: [X86_64H, CPU.x86_64], + index: 1, + architecture: "x86_64", + }, + ])( + "selects one slice when FAT slices $layout share a CPU type", + ({ cpus, index, architecture = "arm64" }) => { + const fat = Buffer.from( + fatImage(cpus.map((cpu) => ({ cpu, bytes: machoImage({ cpu }) }))), + ); + expect(selectMachoSlice(fat, architecture).fatDeclaration).toMatchObject({ + index, + cpuSubtype: cpus[index]?.subtype, + }); + expect(parseMachoLayout(fat, architecture).segments).toEqual([]); + }, + ); + + it("rejects slices of the requested CPU type that share a subtype", () => { + const fat = fatImage( + [CPU.arm64e, CPU.arm64e].map((cpu) => ({ + cpu, + bytes: machoImage({ cpu }), + })), + ); + expect(() => parseMachoLayout(Buffer.from(fat), "arm64")).toThrow( + /Ambiguous FAT architecture slice/u, + ); + }); }); describe("native Mach-O fixup load command boundaries", () => { diff --git a/src/native/AppleMachoSelection.ts b/src/native/AppleMachoSelection.ts index 9ee93f995..c0c68068d 100644 --- a/src/native/AppleMachoSelection.ts +++ b/src/native/AppleMachoSelection.ts @@ -1,7 +1,13 @@ import type { FixupCommands } from "./AppleMachoFixups.js"; +import { + MACHO_ARCHITECTURE_POLICIES, + machoSubtypeRank, +} from "./MachoArchitectureSelection.js"; +import { machoCpuSubtypeBase } from "../domain/apple/machoCpuIdentity.js"; import { readFatSliceDeclarations, validateFatSlice, + type FatSliceDeclaration, } from "../domain/apple/machoContainer.js"; /** One mapped Mach-O segment with file-backed VA range. */ @@ -90,32 +96,44 @@ export const selectMachoSlice = ( const headerEnd = 8 + count * stride; if (count > 128 || headerEnd > bytes.length) throw malformed("Malformed FAT architecture table"); - const cpu = MACHO_CPU_TYPE[architecture]; - if (cpu === undefined) throw invalid("Requested FAT architecture is absent"); + const policy = MACHO_ARCHITECTURE_POLICIES[architecture]; + if (policy === undefined) + throw invalid("Requested FAT architecture is absent"); const declarations = readFatSliceDeclarations(bytes.subarray(8, headerEnd), { count, wide: fat64, littleEndian, }); if (declarations.status !== "parsed") throw malformed(declarations.reason); - let selected: MachoSlice | undefined; + let best: FatSliceDeclaration | undefined; + let bestRank = Number.POSITIVE_INFINITY; + let ambiguous = false; for (const declaration of declarations.slices) { const issue = validateFatSlice(declaration, bytes.length, headerEnd); if (issue !== null) throw malformed(issue); - if (declaration.cpuType !== cpu) continue; - if (selected !== undefined) - throw invalid("Ambiguous FAT architecture slice"); - selected = { - slice: declaration.offset, - sliceEnd: declaration.offset + declaration.size, - fatDeclaration: { - ...declaration, - tableEnd: headerEnd, - }, - }; + if (declaration.cpuType !== policy.cpuType) continue; + const rank = machoSubtypeRank(policy, declaration.cpuSubtype); + if (best !== undefined && rank >= bestRank) { + // Equal ranks keep FAT table order unless the slices share a subtype. + if ( + rank === bestRank && + machoCpuSubtypeBase(declaration.cpuSubtype) === + machoCpuSubtypeBase(best.cpuSubtype) + ) + ambiguous = true; + continue; + } + best = declaration; + bestRank = rank; + ambiguous = false; } - if (selected === undefined) - throw invalid("Requested FAT architecture is absent"); + if (best === undefined) throw invalid("Requested FAT architecture is absent"); + if (ambiguous) throw invalid("Ambiguous FAT architecture slice"); + const selected: MachoSlice = { + slice: best.offset, + sliceEnd: best.offset + best.size, + fatDeclaration: { ...best, tableEnd: headerEnd }, + }; if (selected.slice + 4 > bytes.length) throw malformed("Truncated Mach-O header"); const sliceMagic = bytes.readUInt32LE(selected.slice); @@ -126,13 +144,6 @@ export const selectMachoSlice = ( return selected; }; -/** CPU types admitted by `machArchitecture` in the domain binary target parser. */ -const MACHO_CPU_TYPE: Readonly> = { - x86: 7, - x86_64: 0x01000007, - arm: 12, - arm64: 0x0100000c, -}; const MH_MAGIC = 0xfeedface; const MH_CIGAM = 0xcefaedfe; diff --git a/src/native/MachoArchitectureSelection.ts b/src/native/MachoArchitectureSelection.ts new file mode 100644 index 000000000..14c5f696f --- /dev/null +++ b/src/native/MachoArchitectureSelection.ts @@ -0,0 +1,80 @@ +import { machoCpuSubtypeBase } from "../domain/apple/machoCpuIdentity.js"; +import type { LipoArchitecture } from "./parsers/lipo.js"; + +interface MachoArchitecturePolicy { + readonly cpuType: number; + readonly subtypes: readonly { + readonly subtype: number; + readonly name: string; + }[]; + readonly variantName?: RegExp; +} + +/** One preference order for FAT subtype identities and Apple tool slice names. */ +export const MACHO_ARCHITECTURE_POLICIES: Readonly< + Record +> = { + x86: { cpuType: 7, subtypes: [{ subtype: 3, name: "i386" }] }, + x86_64: { + cpuType: 0x01000007, + subtypes: [{ subtype: 3, name: "x86_64" }], + }, + arm: { cpuType: 12, subtypes: [], variantName: /^arm$/u }, + arm64: { + cpuType: 0x0100000c, + subtypes: [ + { subtype: 0, name: "arm64" }, + { subtype: 2, name: "arm64e" }, + { subtype: 1, name: "arm64v8" }, + ], + variantName: /^arm64e\.[A-Za-z0-9_]+$/u, + }, +}; + +/** Unlisted subtypes follow the preferred slices in FAT table order. */ +export const machoSubtypeRank = ( + policy: MachoArchitecturePolicy, + subtype: number, +): number => { + const rank = policy.subtypes.findIndex( + (candidate) => candidate.subtype === machoCpuSubtypeBase(subtype), + ); + return rank < 0 ? policy.subtypes.length : rank; +}; + +/** Select a tool spelling using the same preference order as FAT selection. */ +export const selectMachoArchitectureName = ( + policy: MachoArchitecturePolicy, + available: readonly LipoArchitecture[], +): string | undefined => { + let selected: string | undefined; + let bestRank = Number.POSITIVE_INFINITY; + for (const architecture of available) { + if ( + architecture.cpu_type_code !== null && + architecture.cpu_type_code !== policy.cpuType + ) + continue; + const namedSubtype = policy.subtypes.find( + ({ name }) => name === architecture.name, + ); + const recognizedName = + namedSubtype !== undefined || policy.variantName?.test(architecture.name); + if ( + !recognizedName && + (architecture.cpu_type_code === null || + architecture.cpu_subtype_base === null) + ) + continue; + // Parsed identity is authoritative. Names support thin/partial lipo records. + const subtype = architecture.cpu_subtype_base ?? namedSubtype?.subtype; + const rank = + subtype === undefined + ? policy.subtypes.length + : machoSubtypeRank(policy, subtype); + if (rank >= bestRank) continue; + selected = architecture.name; + bestRank = rank; + } + return selected; +}; diff --git a/src/native/NativeMachoInspection.test.ts b/src/native/NativeMachoInspection.test.ts index 6fe24eb90..640e540be 100644 --- a/src/native/NativeMachoInspection.test.ts +++ b/src/native/NativeMachoInspection.test.ts @@ -1,10 +1,18 @@ import { describe, expect, it } from "vitest"; +import { + CPU, + LC, + dylibCommand, + fatImage, + machoImage, +} from "../artifacts/apple/MachoImage.fixture.js"; import { AnalysisCancelledError, AnalysisOutputError, } from "../domain/analysisErrorCore.js"; import { err, ok } from "../domain/result.js"; +import { parseMachoLayout, selectMachoSlice } from "./AppleMachoSelection.js"; import type { NativeCommandCapture } from "./CommandRunner.js"; import { inspectNativeMacho } from "./NativeMachoInspection.js"; import { @@ -78,6 +86,62 @@ describe("Mach-O tool architecture selection", () => { "/fixture/app", ]); }); + + it.each([ + { names: ["arm64v8", "arm64e"], selected: "arm64e" }, + { names: ["arm64e", "arm64v8"], selected: "arm64e" }, + { names: ["arm64v8", "arm64e", "arm64"], selected: "arm64" }, + { names: ["arm64v8"], selected: "arm64v8" }, + { names: ["arm64v8", "arm64e.x1"], selected: "arm64v8" }, + { names: ["arm64e.x1", "arm64v8"], selected: "arm64v8" }, + { names: ["arm64v8", "arm64e.v1"], selected: "arm64e.v1" }, + { names: ["arm64e.v1", "arm64v8"], selected: "arm64e.v1" }, + ] as const)( + "keeps inspection and dispatch on $selected for FAT order $names", + async ({ names, selected }) => { + const cpus = { + arm64: CPU.arm64, + arm64v8: { type: CPU.arm64.type, subtype: 1 }, + arm64e: CPU.arm64e, + "arm64e.x1": { type: CPU.arm64.type, subtype: 0x8000000c }, + "arm64e.v1": { type: CPU.arm64.type, subtype: 0x81000002 }, + }; + const slices = names.map((name) => { + const cpu = cpus[name]; + return { + cpu, + bytes: machoImage({ + cpu, + commands: [dylibCommand(LC.LOAD_DYLIB, `/fixture/${name}.dylib`)], + }), + }; + }); + const fat = Buffer.from(fatImage(slices)); + const lipo = names + .map( + (name, index) => + `architecture ${name}\n cputype ${cpus[name].type}\n cpusubtype ${cpus[name].subtype}\n offset ${(index + 1) * 4096}\n size ${slices[index]?.bytes.length}\n align 2^12\n`, + ) + .join(""); + const { commands } = await inspect(lipo, "arm64"); + expect(commands.find(({ tool }) => tool === "otool")?.args).toEqual([ + "-h", + "-l", + "-arch", + selected.split(".")[0], + "/fixture/app", + ]); + expect(commands.find(({ tool }) => tool === "dyld_info")?.args).toContain( + selected, + ); + expect(selectMachoSlice(fat, "arm64").slice).toBe( + (names.findIndex((name) => name === selected) + 1) * 4096, + ); + expect(parseMachoLayout(fat, "arm64").fixups.dylibs).toEqual([ + `/fixture/${selected}.dylib`, + ]); + }, + ); }); describe("Mach-O UUID reconciliation", () => { diff --git a/src/native/NativeMachoInspection.ts b/src/native/NativeMachoInspection.ts index 24ccb2514..5fca089cb 100644 --- a/src/native/NativeMachoInspection.ts +++ b/src/native/NativeMachoInspection.ts @@ -9,8 +9,15 @@ import { import { jsonValueSchema, type JsonValue } from "../domain/jsonValue.js"; import { err, ok, type Result } from "../domain/result.js"; import type { NativeCommandCapture } from "./CommandRunner.js"; +import { + MACHO_ARCHITECTURE_POLICIES, + selectMachoArchitectureName, +} from "./MachoArchitectureSelection.js"; import { parseDyldSymbols } from "./parsers/dyldInfo.js"; -import { parseLipoArchitectures } from "./parsers/lipo.js"; +import { + parseLipoArchitectures, + type LipoArchitecture, +} from "./parsers/lipo.js"; import { withoutEchoedPathHeader } from "./parsers/echoedPath.js"; import { parseOtoolLoadCommands } from "./parsers/otool.js"; import { reconcileMachoUuid } from "./parsers/machoUuid.js"; @@ -68,8 +75,7 @@ export const inspectNativeMacho = async ( const lipo = captures.find(({ tool }) => tool === "lipo"); if (lipo === undefined) throw new TypeError("Missing lipo capture"); const architectures = parseLipoArchitectures(lipo.stdout); - const availableArchitectures = architectures.map(({ name }) => name); - const selection = selectArchitecture(context.target, availableArchitectures); + const selection = selectArchitecture(context.target, architectures); if (selection.status === "absent") return err( new AnalysisOutputError( @@ -397,25 +403,24 @@ type ArchitectureSelection = const selectArchitecture = ( target: BinaryTarget, - available: readonly string[], + available: readonly LipoArchitecture[], ): ArchitectureSelection => { - if (target.kind !== "executable" || target.availableArchitectures.length < 2) + // BinaryTarget lists CPU families and lipo lists slices. A universal file + // can hold several slices of one family (arm64e and arm64e.x1), and slice + // tools without -arch print every slice. + if ( + target.kind !== "executable" || + (target.availableArchitectures.length < 2 && available.length < 2) + ) return { status: "unfiltered" }; const normalized = target.architecture === "x86" ? "i386" : target.architecture; - if (available.includes(normalized)) - return { status: "selected", architecture: normalized }; - // BinaryTarget intentionally normalizes ARM64 CPU subtypes. Recover the - // concrete arm64e slice name from lipo before invoking slice-aware tools. - if (normalized === "arm64") { - const arm64e = available.find((architecture) => architecture === "arm64e"); - if (arm64e !== undefined) - return { status: "selected", architecture: arm64e }; - const variant = available.find((architecture) => - /^arm64e\.[A-Za-z0-9_]+$/u.test(architecture), - ); - if (variant !== undefined) - return { status: "selected", architecture: variant }; - } + const policy = MACHO_ARCHITECTURE_POLICIES[target.architecture]; + const selected = + policy === undefined + ? available.find(({ name }) => name === normalized)?.name + : selectMachoArchitectureName(policy, available); + if (selected !== undefined) + return { status: "selected", architecture: selected }; return { status: "absent", architecture: normalized }; }; diff --git a/src/native/parsers/codesign.ts b/src/native/parsers/codesign.ts index 3a39a389e..74a472f33 100644 --- a/src/native/parsers/codesign.ts +++ b/src/native/parsers/codesign.ts @@ -16,14 +16,11 @@ export const parseCodeSignature = ( unsigned: boolean, executablePaths: readonly string[] = [], ): Omit => { - const { identifier, fields } = splitEchoedValues( - output.replaceAll("\r\n", "\n"), - executablePaths, - ); + const { identifier, fields } = splitEchoedValues(output, executablePaths); const values = new Map(); const authorities: string[] = []; const cdhashes: string[] = []; - for (const line of fields.split("\n")) { + for (const line of fields.split(/\r?\n/u)) { if (line.startsWith("CodeDirectory ")) { values.set("CodeDirectory", line.slice("CodeDirectory ".length)); continue; @@ -65,12 +62,20 @@ const splitEchoedValues = ( text: string, executablePaths: readonly string[], ): { readonly identifier: string | undefined; readonly fields: string } => { - const executable = executablePaths - .map((path) => `Executable=${path}\n`) - .find((line) => text.startsWith(line)); let rest = text; - if (executable !== undefined) rest = text.slice(executable.length); - else if (text.startsWith("Executable=")) { + // Frame the exact source path before interpreting record separators. A CRLF + // inside that path or the signing identifier is payload, not a line ending. + let newline: string | undefined; + for (const path of executablePaths) { + const prefix = `Executable=${path}`; + if (!text.startsWith(prefix)) continue; + const separator = /^\r?\n/u.exec(text.slice(prefix.length))?.[0]; + if (separator === undefined) continue; + newline = separator; + rest = text.slice(prefix.length + separator.length); + break; + } + if (rest === text && text.startsWith("Executable=")) { const identifierLine = text.indexOf("\nIdentifier="); rest = identifierLine < 0 ? text : text.slice(identifierLine + 1); } @@ -79,8 +84,17 @@ const splitEchoedValues = ( // Later fields come from the signature itself, so the last `Format=` line // is the one codesign printed after the identifier. const format = rest.lastIndexOf("\nFormat="); - const lineEnd = rest.indexOf("\n"); - const end = format >= 0 ? format : lineEnd >= 0 ? lineEnd : rest.length; + // Without an exact path, use the producer-owned Format record's terminator. + // Looking inside Identifier instead would confuse literal CRLF payload with + // record framing, or strip a literal trailing CR from an LF-delimited value. + if (newline === undefined && format >= 0) + newline = /\r?\n/u.exec(rest.slice(format + 1))?.[0]; + const boundary = format >= 0 ? format : rest.indexOf("\n"); + const crlf = newline === undefined || newline === "\r\n"; + const end = + boundary < 0 + ? rest.length + : boundary - (crlf && rest[boundary - 1] === "\r" ? 1 : 0); return { identifier: rest.slice("Identifier=".length, end), fields: rest.slice(end), diff --git a/src/native/parsers/lipo.test.ts b/src/native/parsers/lipo.test.ts index 43f08d8b8..96f2afbbc 100644 --- a/src/native/parsers/lipo.test.ts +++ b/src/native/parsers/lipo.test.ts @@ -59,6 +59,7 @@ architecture arm64e cpu_type_code: null, cpu_subtype: "CPU_SUBTYPE_FUTURE", cpu_subtype_code: null, + cpu_subtype_base: null, }, ]); }); @@ -85,8 +86,29 @@ architecture arm64e { cpu_subtype: "CPU_SUBTYPE_X86_ALL", cpu_subtype_code: null, + cpu_subtype_base: 3, capabilities: null, }, ]); }); + + it.each([ + { capabilities: "PTR_AUTH_VERSION USERSPACE 1", code: 0x81000002 }, + { capabilities: "", code: null }, + ])( + "retains an arm64e base subtype with capabilities '$capabilities'", + ({ capabilities, code }) => { + expect( + parseLipoArchitectures( + `architecture arm64e.v1\n cputype CPU_TYPE_ARM64\n cpusubtype CPU_SUBTYPE_ARM64E\n capabilities ${capabilities}\n`, + ), + ).toMatchObject([ + { + cpu_type_code: 0x0100000c, + cpu_subtype_code: code, + cpu_subtype_base: 2, + }, + ]); + }, + ); }); diff --git a/src/native/parsers/lipo.ts b/src/native/parsers/lipo.ts index 4f56d8b6b..cc65cca41 100644 --- a/src/native/parsers/lipo.ts +++ b/src/native/parsers/lipo.ts @@ -1,4 +1,5 @@ import { z } from "zod"; +import { machoCpuSubtypeBase } from "../../domain/apple/machoCpuIdentity.js"; const architectureSchema = z.object({ name: z.string().min(1), @@ -6,6 +7,7 @@ const architectureSchema = z.object({ cpu_subtype: z.string().nullable(), cpu_type_code: z.number().int().nonnegative().nullable(), cpu_subtype_code: z.number().int().nonnegative().nullable(), + cpu_subtype_base: z.number().int().nonnegative().nullable(), capabilities: z.string().nullable(), file_offset: z.number().int().min(0).nullable(), size: z.number().int().min(0).nullable(), @@ -30,6 +32,7 @@ export const parseLipoArchitectures = (output: string): LipoArchitecture[] => { cpu_subtype: null, cpu_type_code: null, cpu_subtype_code: null, + cpu_subtype_base: null, capabilities: null, file_offset: null, size: null, @@ -54,6 +57,7 @@ export const parseLipoArchitectures = (output: string): LipoArchitecture[] => { current.cpusubtype, current.capabilities, ), + cpu_subtype_base: cpuSubtypeBase(current.cpusubtype), capabilities: current.capabilities ?? null, file_offset: integer(current.offset), size: integer(current.size), @@ -158,10 +162,10 @@ const cpuSubtypeCode = ( }; /** The subtype bits a lipo record names, without its capability byte. */ -export const lipoSubtypeBits = (value: string | null): number | null => { - if (value === null) return null; +const cpuSubtypeBase = (value: string | undefined): number | null => { + if (value === undefined) return null; const subtype = unsigned32(value) ?? CPU_SUBTYPES[value]; - return subtype === undefined ? null : subtype & 0x00ffffff; + return subtype === undefined ? null : machoCpuSubtypeBase(subtype); }; /** lipo names the LIB64 capability and prints other capability bits in hex. */ diff --git a/tests/acceptance/applications/bundlerCallbackMetadataCli.test.ts b/tests/acceptance/applications/bundlerCallbackMetadataCli.test.ts new file mode 100644 index 000000000..1f3987237 --- /dev/null +++ b/tests/acceptance/applications/bundlerCallbackMetadataCli.test.ts @@ -0,0 +1,61 @@ +import { writeFile } from "node:fs/promises"; +import { join } from "node:path"; +import { expect } from "vitest"; +import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js"; +import { cliTest } from "../../support/cli/cliFixture.js"; +import { analyzeJavaScriptDirectory } from "../../support/cli/javascriptApplication.js"; + +cliTest.for(["CLI", "stdio MCP"] as const)( + "retains both repeated chunk callback observations through %s", + async (surface, { cli }) => { + const root = await createTestTempDirectory("rea-bundler-callbacks-"); + const source = [ + '(globalThis.webpackChunkFixture = globalThis.webpackChunkFixture || []).push([[1], {a: function() {}}, function(r) { r(7); r.e("chunk-a"); }]);', + '(globalThis.webpackChunkFixture = globalThis.webpackChunkFixture || []).push([[1], {a: function() {}}, function(r) { r(8); r.e("chunk-b"); }]);', + ].join("\n"); + await writeFile(join(root, "bundle.js"), source); + const { graph } = await analyzeJavaScriptDirectory(surface, cli, root); + const chunk = graph.nodes.find(({ kind }) => kind === "javascript-chunk"); + for (const [index, entry, asyncChunk] of [ + [0, "7", "chunk-a"], + [1, "8", "chunk-b"], + ] as const) { + expect(chunk?.observations).toContainEqual( + expect.objectContaining({ + properties: expect.objectContaining({ + entry_module_keys: [entry], + async_chunk_keys: [asyncChunk], + }), + evidence: expect.objectContaining({ + location: expect.objectContaining({ + value: expect.objectContaining({ + source: "bundle.js", + start: { line: index + 1, column: 0 }, + }), + }), + }), + }), + ); + expect(graph.edges).toContainEqual( + expect.objectContaining({ + source_node_id: chunk?.node_id, + properties: expect.objectContaining({ + kind: "bundler-entry-module", + module_key: entry, + resolution_status: "not-found", + }), + }), + ); + expect(graph.edges).toContainEqual( + expect.objectContaining({ + source_node_id: chunk?.node_id, + properties: expect.objectContaining({ + kind: "bundler-async-chunk", + chunk_key: asyncChunk, + resolution_status: "not-found", + }), + }), + ); + } + }, +); diff --git a/tests/acceptance/applications/nibFieldIdentity.test.ts b/tests/acceptance/applications/nibFieldIdentity.test.ts new file mode 100644 index 000000000..5af16f890 --- /dev/null +++ b/tests/acceptance/applications/nibFieldIdentity.test.ts @@ -0,0 +1,110 @@ +import { Client } from "@modelcontextprotocol/client"; +import { StdioClientTransport } from "@modelcontextprotocol/client/stdio"; +import { createHash } from "node:crypto"; +import { mkdir, readFile, writeFile } from "node:fs/promises"; +import { join, resolve } from "node:path"; +import { expect } from "vitest"; + +import { encodeNibArchiveFixture } from "../../../src/artifacts/apple/NibArchive.fixture.js"; +import { toolContract } from "../../../src/contracts/toolContracts.js"; +import { interfaceBuilderAnalysisSchema } from "../../../src/domain/apple/interfaceBuilderGraph.js"; +import { thinMach } from "../../../src/domain/binaryTarget.fixture.js"; +import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js"; +import { cliTest } from "../../support/cli/cliFixture.js"; + +cliTest( + "preserves literal NIB fields and UTF-8 names through CLI and stdio MCP", + async ({ cli }) => { + const root = await createTestTempDirectory("rea-nib-field-identity-"); + const app = join(root, "Fixture.app"); + const contents = join(app, "Contents"); + await mkdir(join(contents, "Resources"), { recursive: true }); + await mkdir(join(contents, "MacOS")); + await writeFile( + join(contents, "MacOS/App"), + thinMach(0xfeedfacf, 0x0100000c), + ); + await writeFile( + join(contents, "Info.plist"), + "CFBundleExecutableAppCFBundleIdentifierdev.rea.nib-fields", + ); + const archive = encodeNibArchiveFixture({ + classes: ["UIView", "\uFEFFCustomView"], + objects: [ + { + classIndex: 0, + values: { + ["__proto__"]: { ref: 1 }, + constructor: 7, + enabled: true, + "\uFEFFenabled": false, + }, + }, + { classIndex: 1, values: { ["__proto__"]: 23 } }, + ], + }); + const path = join(contents, "Resources/Panel.nib"); + await writeFile(path, archive); + const result = await cli.run({ + arguments: ["decode-interface-builder", app, "--json"], + environment: { REA_LOG_LEVEL: "silent", REA_ANALYSIS_PROVIDER: "auto" }, + }); + expect(result.exitCode, result.stdout + result.stderr).toBe(0); + const contract = toolContract("decode_interface_builder"); + const evidence = contract.outputSchema.parse(result.json); + const transport = new StdioClientTransport({ + command: process.execPath, + args: [resolve("scripts/rea.mjs"), "mcp"], + env: { + PATH: process.env.PATH ?? "", + REA_LOG_LEVEL: "silent", + REA_ANALYSIS_PROVIDER: "auto", + }, + stderr: "pipe", + }); + const client = new Client({ name: "nib-field-identity", version: "1" }); + try { + await client.connect(transport); + const opened = await client.callTool({ + name: "open_binary", + arguments: { path: app }, + }); + expect(opened.isError, JSON.stringify(opened)).not.toBe(true); + const response = await client.callTool({ + name: contract.name, + arguments: {}, + }); + expect(response.isError, JSON.stringify(response)).not.toBe(true); + const mcp = contract.outputSchema.parse(response.structuredContent); + expect(mcp.normalized_result).toEqual(evidence.normalized_result); + } finally { + try { + await client.close(); + } finally { + await transport.close(); + } + } + const report = interfaceBuilderAnalysisSchema.parse( + evidence.normalized_result, + ); + expect(report.documents[0]?.archive_sha256).toBe( + createHash("sha256").update(archive).digest("hex"), + ); + const objects = report.graph.nodes.filter( + ({ attributes }) => attributes.interface_builder_object_id !== undefined, + ); + expect(objects).toHaveLength(2); + expect(objects[0]?.attributes.nibValues).toEqual({ + ["__proto__"]: { objectID: "1" }, + constructor: 7, + enabled: true, + "\uFEFFenabled": false, + }); + expect(objects[1]?.attributes).toMatchObject({ + class_name: "\uFEFFCustomView", + nibValues: { ["__proto__"]: 23 }, + }); + expect(await readFile(path)).toEqual(archive); + }, + 60_000, +); diff --git a/tests/boundary/cli/analysisSelectorCli.test.ts b/tests/boundary/cli/analysisSelectorCli.test.ts index 404cad6a2..5e89daa2b 100644 --- a/tests/boundary/cli/analysisSelectorCli.test.ts +++ b/tests/boundary/cli/analysisSelectorCli.test.ts @@ -12,6 +12,38 @@ const selectors = [ ] as const; describe("CLI analysis selector boundaries", () => { + cliTest( + "accepts file offsets and rejects mixed coordinate selectors before opening a target", + async ({ cli }) => { + const selected = await cli.run({ + arguments: [ + "decompile", + "does-not-exist", + "--file-offset=0x210", + "--json", + ], + environment: { REA_LOG_LEVEL: "silent" }, + }); + expect(selected.json).toMatchObject({ code: "target_unavailable" }); + const conflicting = await cli.run({ + arguments: [ + "decompile", + "does-not-exist", + "0x140001010", + "--file-offset=0x210", + "--json", + ], + environment: { REA_LOG_LEVEL: "silent" }, + }); + expect(conflicting.json).toMatchObject({ + code: "invalid_request", + details: { + operation: "procedure_pseudo_code", + issues: [{ path: ["file-offset"], reason: "invalid_value" }], + }, + }); + }, + ); cliTest( "rejects missing and conflicting selectors before opening a target", async ({ cli }) => { diff --git a/tests/boundary/cli/apktoolBooleanOptions.test.ts b/tests/boundary/cli/apktoolBooleanOptions.test.ts new file mode 100644 index 000000000..5c5578c18 --- /dev/null +++ b/tests/boundary/cli/apktoolBooleanOptions.test.ts @@ -0,0 +1,85 @@ +import { expect, it } from "vitest"; +import { Cli } from "incur"; +import pino from "pino"; + +import type { ApktoolResourceAnalysisPort } from "../../../src/application/apktool/ApktoolResourceAnalysisPort.js"; +import { createAnalysisExecution } from "../../../src/application/AnalysisProvider.js"; +import { registerApktoolCommands } from "../../../src/cli/apktoolCommands.js"; +import { presentOmittableDefaults } from "../../../src/cli/omittableDefaults.js"; +import type { ApktoolRequest } from "../../../src/domain/apktool/apktoolResourceAnalysis.js"; +import { ok } from "../../../src/domain/result.js"; + +const invoke = async (argv: readonly string[]) => { + const requests: ApktoolRequest[] = []; + const provider: ApktoolResourceAnalysisPort = { + async inspectAvailability() { + throw new Error("unexpected provider probe"); + }, + async close() {}, + async execute(request) { + requests.push(request); + return ok( + createAnalysisExecution( + { strings: [] }, + { id: "apktool", name: "Apktool", version: null }, + ), + ); + }, + }; + const cli = Cli.create("rea", { sync: false }); + registerApktoolCommands(cli, pino({ level: "silent" }), {}, provider); + presentOmittableDefaults(cli); + + let stdout = ""; + let exitCode = 0; + await cli.serve([...argv], { + env: {}, + exit: (code) => { + exitCode = code; + }, + stdout: (text) => { + stdout += text; + }, + }); + return { exitCode, stdout, requests }; +}; + +it("dispatches --no-strings as include_strings false", async () => { + const result = await invoke([ + "decode-android-resources", + "/targets/app.apk", + "--no-strings", + "--json", + ]); + + expect(result.exitCode).toBe(0); + expect(result.requests).toEqual([ + { + operation: "decode_android_resources", + input: { path: "/targets/app.apk", include_strings: false }, + }, + ]); +}); + +it("keeps string projection enabled when the flag is omitted", async () => { + const result = await invoke([ + "decode-android-resources", + "/targets/app.apk", + "--json", + ]); + + expect(result.exitCode).toBe(0); + expect(result.requests).toEqual([ + { + operation: "decode_android_resources", + input: { path: "/targets/app.apk", include_strings: true }, + }, + ]); +}); + +it("documents the supported negative flag in command help", async () => { + const result = await invoke(["decode-android-resources", "--help"]); + + expect(result.exitCode).toBe(0); + expect(result.stdout).toContain("--no-strings"); +}); diff --git a/tests/boundary/cli/dylibResolutionCli.test.ts b/tests/boundary/cli/dylibResolutionCli.test.ts index b74dae71e..66fa21ba3 100644 --- a/tests/boundary/cli/dylibResolutionCli.test.ts +++ b/tests/boundary/cli/dylibResolutionCli.test.ts @@ -4,11 +4,13 @@ import { dirname, join } from "node:path"; import { describe, expect } from "vitest"; import { + CPU, FILE_TYPE, LC, buildVersionCommand, dylibCommand, dyldEnvironmentCommand, + fatImage, machoImage, rpathCommand, } from "../../../src/artifacts/apple/MachoImage.fixture.js"; @@ -471,6 +473,64 @@ cliTest( }, ); +cliTest( + "reports each same-named slice's own embedded dyld environment", + async ({ cli }) => { + // arm64e and arm64e.x1 slices both report the architecture name arm64e. + // A plain x86_64 slice keeps the bundle openable on x64 hosts. + for (const [settings, expected] of [ + [[null, "DYLD_PRINT_RPATHS=1"], ["DYLD_PRINT_RPATHS=1"]], + [ + ["DYLD_PRINT_LIBRARIES=1", "DYLD_PRINT_RPATHS=1"], + ["DYLD_PRINT_LIBRARIES=1", "DYLD_PRINT_RPATHS=1"], + ], + ] as const) { + const app = await fixtureApp(); + await writeFiles(app, { + "Contents/MacOS/App": fatImage([ + ...[CPU.arm64e, CPU.arm64eX1].map((cpu, index) => { + const setting = settings[index]; + return { + cpu, + bytes: machoImage({ + cpu, + commands: + setting === null || setting === undefined + ? [] + : [dyldEnvironmentCommand(setting)], + }), + }; + }), + { cpu: CPU.x86_64, bytes: machoImage({ cpu: CPU.x86_64 }) }, + ]), + }); + const result = await cli.run({ + arguments: [ + "trace-dylib-resolution", + app, + "--root", + "Contents/MacOS/App", + "--json", + ], + environment: ENVIRONMENT, + }); + expect(result.exitCode, JSON.stringify(result.json)).toBe(0); + const trace = dylibResolutionResultSchema.parse( + parseEvidence(result.json).normalized_result, + ); + expect( + trace.roots.filter(({ architecture }) => architecture === "arm64e"), + ).toHaveLength(2); + const environments = trace.findings + .filter(({ kind }) => kind === "dyld-environment-present") + .map(({ explanation }) => + expected.filter((setting) => explanation.includes(setting)), + ); + expect(environments).toEqual(expected.map((setting) => [setting])); + } + }, +); + cliTest( "retains definitive load findings for an explicitly selected app library root", async ({ cli }) => { diff --git a/tests/boundary/cli/nativeSignatureCli.test.ts b/tests/boundary/cli/nativeSignatureCli.test.ts index 9302d9c24..e30581db4 100644 --- a/tests/boundary/cli/nativeSignatureCli.test.ts +++ b/tests/boundary/cli/nativeSignatureCli.test.ts @@ -21,14 +21,14 @@ const adHocProgram = async (directory: string, name: string) => { describe.skipIf(process.platform !== "darwin")( "native signature CLI with echoed path text", () => { - cliTest( - "does not read signature fields from the file name codesign echoes", - async ({ cli }) => { + cliTest.for(["\n", "\r\n"])( + "does not read signature fields from the file name codesign echoes (%j)", + async (newline, { cli }) => { const directory = await createTestTempDirectory("rea-signature-"); const forged = "Developer ID Application: Example (ABCDE12345)"; const program = await adHocProgram( directory, - `tool\nAuthority=${forged}\nTeamIdentifier=ABCDE12345`, + `tool${newline}Authority=${forged}${newline}Identifier=forged${newline}TeamIdentifier=ABCDE12345`, ); const unsignedName = await adHocProgram( directory, @@ -75,7 +75,7 @@ describe.skipIf(process.platform !== "darwin")( normalized_result: { identifier: expect.stringMatching( new RegExp( - `^tool\\nAuthority=${forged.replace(/[()]/gu, "\\$&")}\\nTeamIdentifier=ABCDE12345-`, + `^tool${newline}Authority=${forged.replace(/[()]/gu, "\\$&")}${newline}Identifier=forged${newline}TeamIdentifier=ABCDE12345-`, "u", ), ), diff --git a/tests/boundary/filesystem/artifactZipIntegrity.test.ts b/tests/boundary/filesystem/artifactZipIntegrity.test.ts index 0bb475518..41397c520 100644 --- a/tests/boundary/filesystem/artifactZipIntegrity.test.ts +++ b/tests/boundary/filesystem/artifactZipIntegrity.test.ts @@ -38,8 +38,19 @@ it("completes an empty ZIP extraction with an empty identity", async () => { expect(await readdir(output)).toEqual([]); }); +const legacyControlNames = [ + ["legacy ASCII control", Buffer.from("Icon\r"), false, "Icon\r"], + [ + "legacy CP437 control", + Buffer.from([0x82, 0x09, 0x7f, 0x2e, 0x61]), + false, + "é\t\u007F.a", + ], +] as const; + it.each([ ["legacy CP437", Buffer.from([0x82, 0x2e, 0x74, 0x78, 0x74]), false, "é.txt"], + ...legacyControlNames, [ "EFS with leading U+FEFF", Buffer.from([0xef, 0xbb, 0xbf, 0x61, 0x62]), @@ -68,6 +79,38 @@ it.each([ }, ); +it.skipIf(process.platform === "win32").each(legacyControlNames)( + "extracts %s ZIP members under their stored names", + async (_label, rawName, utf8Flag, logicalPath) => { + const root = await createTestTempDirectory("rea-zip-extracted-name-"); + const path = join(root, "names.zip"); + await writeSingleEntryZip(path, "x.txt"); + const archive = await readFile(path); + await writeFile( + path, + rewriteSingleEntryName(archive, "x.txt", rawName, utf8Flag), + ); + const target = await parseBinaryTarget(path); + if (!target.ok) throw target.error; + + const output = join(root, "output"); + const result = await withArtifactClient(target.value, (client) => + client.execute("extract_artifact", { output_root: output }), + ); + if (!result.ok) throw result.error; + const extraction = artifactExtractionResultSchema.parse( + result.value.result, + ); + expect( + extraction.artifacts.map(({ relative_path }) => relative_path), + ).toEqual([logicalPath]); + expect(await readdir(output)).toEqual([logicalPath]); + expect(await readFile(join(output, logicalPath), "utf8")).toBe( + "member bytes", + ); + }, +); + it("preserves valid Info-ZIP Unicode Path overrides", async () => { const root = await createTestTempDirectory("rea-zip-unicode-path-"); const path = join(root, "unicode-path.zip"); diff --git a/tests/boundary/filesystem/ciChangeScope.test.ts b/tests/boundary/filesystem/ciChangeScope.test.ts index fcce47693..b1fd64a04 100644 --- a/tests/boundary/filesystem/ciChangeScope.test.ts +++ b/tests/boundary/filesystem/ciChangeScope.test.ts @@ -1,4 +1,5 @@ import { + chmod, cp, mkdir, readFile, @@ -79,6 +80,7 @@ async function classify( head: string, event = "pull_request", full = false, + skipFull = false, ) { const output = join(directory, "scope-output"); await writeFile(output, ""); @@ -93,6 +95,7 @@ async function classify( HEAD_SHA: head, GITHUB_EVENT_NAME: event, CI_FULL: String(full), + CI_SKIP_FULL: String(skipFull), GITHUB_OUTPUT: output, }, }, @@ -100,6 +103,21 @@ async function classify( return z.record(z.string(), z.unknown()).parse(JSON.parse(result.stdout)); } +it("reuses only scheduled qualification and preserves every explicit full request", async () => { + const { directory, base } = await fixture(); + const reused = await classify(directory, base, base, "schedule", false, true); + expect(reused.tier).toBe("reused"); + const { CI_FLAGS } = await loadScopes(); + for (const flag of CI_FLAGS) expect(reused[flag]).toBe(false); + for (const event of ["workflow_dispatch", "pull_request", "schedule"]) + expect( + (await classify(directory, base, base, event, true, true)).tier, + ).toBe("full"); + expect( + (await classify(directory, base, base, "push", false, true)).tier, + ).toBe("fast"); +}); + it("keeps every translated root README and authored guide on the documentation lane", async () => { const { directory, base } = await fixture(); const readmes = (await readdir(new URL("../../../", import.meta.url))).filter( @@ -119,6 +137,64 @@ it("keeps every translated root README and authored guide on the documentation l }); }); +it.each([ + "job-timings.mjs", + "job-timings-batch.mjs", + "test-report.mjs", + "test-timing-reporter.mjs", + "test-history.mjs", +])( + "keeps portable CI reporter %s on static checks and portable tests", + async (name) => { + const { directory, base } = await fixture(); + const head = await change(directory, [`scripts/ci/${name}`]); + const plan = await classify(directory, base, head); + const { CI_FLAGS } = await loadScopes(); + expect(plan.code).toBe(true); + for (const flag of CI_FLAGS) + if (flag !== "code") expect(plan[flag]).toBe(false); + }, +); + +it("preserves a provider lane when a portable CI reporter changes with provider source", async () => { + const { directory, base } = await fixture(); + const head = await change(directory, [ + "scripts/ci/test-report.mjs", + "src/evm/Example.ts", + ]); + expect(await classify(directory, base, head)).toMatchObject({ + code: true, + evm: true, + browser: false, + package: false, + }); +}); + +it("keeps unknown CI scripts on complete qualification", async () => { + const { directory, base } = await fixture(); + const head = await change(directory, ["scripts/ci/new-qualification.mjs"]); + const plan = await classify(directory, base, head); + const { CI_FLAGS } = await loadScopes(); + for (const flag of CI_FLAGS) expect(plan[flag]).toBe(true); +}); + +it("emits an observational owner proposal without changing ordinary or full portable execution", async () => { + const { directory, base } = await fixture(); + const head = await change(directory, ["src/evm/Example.ts"]); + expect(await classify(directory, base, head)).toMatchObject({ + code: true, + testSelection: { mode: "candidate", owners: ["evm"] }, + }); + expect( + await classify(directory, base, head, "pull_request", true), + ).toMatchObject({ + code: true, + testSelection: { mode: "full", owners: [] }, + }); + const output = await readFile(join(directory, "scope-output"), "utf8"); + expect(output).toContain('test_selection={"version":1,"mode":"full"'); +}); + it("does not charge a documentation PR for unrelated implementation updates on main", async () => { const { directory, base } = await fixture(); await git(directory, ["switch", "-c", "docs/change"]); @@ -162,13 +238,148 @@ it("retains complete checks when implementation is renamed into documentation", }); }); -it("retains the complete main-push baseline even for documentation", async () => { +it("keeps main pushes scoped when a successful ancestor baseline is available", async () => { const { directory, base } = await fixture(); const head = await change(directory, ["README_ja.md"]); expect(await classify(directory, base, head, "push")).toMatchObject({ + tier: "fast", + code: false, + package: false, + docs: true, + matrix: { + include: [ + { os: "ubuntu-latest", platform: "linux", architecture: "x64" }, + ], + }, + }); +}); + +it("includes changes from earlier cancelled pushes since the last successful baseline", async () => { + const { directory, base } = await fixture(); + await change(directory, ["src/evm/client.ts"]); + const head = await change(directory, ["README.md"]); + expect(await classify(directory, base, head, "push")).toMatchObject({ + tier: "fast", + code: true, + evm: true, + runtime: true, + package: false, + }); +}); + +it.each(["", "not-a-commit"])( + "fails closed to all lanes for a missing or invalid push baseline (%s)", + async (base) => { + const { directory } = await fixture(); + const head = await change(directory, ["README.md"]); + const plan = await classify(directory, base, head, "push"); + expect(plan).toMatchObject({ + tier: "fast", + code: true, + package: true, + evm: true, + browser: true, + reasons: expect.arrayContaining([expect.stringContaining("baseline")]), + }); + const { CI_FLAGS } = await loadScopes(); + for (const flag of CI_FLAGS) expect(plan[flag]).toBe(true); + }, +); + +it("selects only a trusted successful ancestor from recent CI push runs", async () => { + const { directory, base } = await fixture(); + const head = await change(directory, ["src/evm/client.ts"]); + const bin = join(directory, "fake-bin"); + await mkdir(bin); + const gh = join(bin, "gh"); + await writeFile(gh, '#!/bin/sh\ncat "$GH_FIXTURE_RESPONSE"\n'); + await chmod(gh, 0o755); + const response = join(directory, "runs.json"); + await writeFile( + response, + JSON.stringify({ + workflow_runs: [ + { + event: "push", + conclusion: "success", + head_branch: "main", + head_repository: { full_name: "untrusted/fork" }, + head_sha: base, + }, + { + event: "push", + conclusion: "success", + head_branch: "main", + head_repository: { full_name: "owner/repo" }, + head_sha: base, + }, + ], + }), + ); + const output = join(directory, "baseline-output"); + const result = await execFileAsync( + process.execPath, + [new URL("../../../scripts/ci/baseline.mjs", import.meta.url).pathname], + { + cwd: directory, + env: { + ...process.env, + PATH: `${bin}:${process.env.PATH}`, + GH_FIXTURE_RESPONSE: response, + CI_REPOSITORY: "owner/repo", + CI_DEFAULT_BRANCH: "main", + HEAD_SHA: head, + GITHUB_OUTPUT: output, + }, + }, + ); + expect(JSON.parse(result.stdout)).toEqual({ base, reason: "" }); + expect(await readFile(output, "utf8")).toBe(`base=${base}\nreason=\n`); +}); + +it("returns an empty baseline when GitHub lookup fails", async () => { + const { directory, base } = await fixture(); + const head = await change(directory, ["src/evm/client.ts"]); + const bin = join(directory, "fake-bin"); + await mkdir(bin); + const gh = join(bin, "gh"); + await writeFile(gh, "#!/bin/sh\nexit 1\n"); + await chmod(gh, 0o755); + const result = await execFileAsync( + process.execPath, + [new URL("../../../scripts/ci/baseline.mjs", import.meta.url).pathname], + { + cwd: directory, + env: { + ...process.env, + PATH: `${bin}:${process.env.PATH}`, + CI_REPOSITORY: "owner/repo", + CI_DEFAULT_BRANCH: "main", + HEAD_SHA: head, + }, + }, + ); + expect(JSON.parse(result.stdout)).toMatchObject({ + base: "", + reason: expect.stringContaining("Could not read"), + }); + expect(head).not.toBe(base); +}); + +it("fails closed when the successful push baseline is not an ancestor", async () => { + const { directory, base } = await fixture(); + await git(directory, ["switch", "-c", "unrelated"]); + const unrelated = await change(directory, ["other.txt"]); + await git(directory, ["switch", "main"]); + const head = await change(directory, ["README.md"]); + expect(await classify(directory, unrelated, head, "push")).toMatchObject({ + tier: "fast", code: true, package: true, + evm: true, + browser: true, }); + expect(head).not.toBe(base); }); it("fails classification rather than treating an invalid Git comparison as a scope", async () => { @@ -208,7 +419,8 @@ it("retains native Inspector verification on every documented package host", asy ); expect(packageInspector.if).toBeUndefined(); expect( - (await classify((await fixture()).directory, "", "", "push")).matrix, + (await classify((await fixture()).directory, "", "", "workflow_dispatch")) + .matrix, ).toEqual({ include: [ { os: "ubuntu-latest", platform: "linux", architecture: "x64" }, @@ -228,7 +440,14 @@ it("retains native Inspector verification on every documented package host", asy it.each([ [ "src/evm/client.ts", - { code: true, runtime: true, evm: true, browser: false, package: false }, + { + code: true, + runtime: true, + evm: true, + browser: false, + package: false, + sqlite: false, + }, ], [ "src/browser/execution/evaluate.ts", @@ -349,6 +568,38 @@ it.each([ "src/process/ProcessOwnership.test.ts", { code: true, package: true, apple: false, evm: false, browser: false }, ], + [ + "src/sqlite/SqliteDatabaseProvider.ts", + { code: true, sqlite: true, runtime: true, package: false }, + ], + [ + "src/application/sqlite/SqliteDatabaseService.test.ts", + { code: true, sqlite: true, runtime: false }, + ], + [ + "tests/boundary/sqlite/sqliteDatabaseProvider.test.ts", + { code: true, sqlite: true, runtime: false }, + ], + [ + "tests/fixtures/sqlite/database.ts", + { code: true, sqlite: true, runtime: false }, + ], + ["tests/acceptance/sqliteDatabaseCli.test.ts", { code: true, sqlite: true }], + [ + "tests/boundary/mcp/serverLifecycleMcp.test.ts", + { code: true, sqlite: true }, + ], + ["src/process/OwnedCommand.ts", { code: true, sqlite: true, runtime: true }], + ["src/server/createServer.ts", { code: true, sqlite: true, runtime: true }], + [ + "src/contracts/toolContracts.ts", + { code: true, sqlite: true, runtime: true }, + ], + [ + "src/domain/analysisErrorProjection.ts", + { code: true, sqlite: true, runtime: true }, + ], + ["src/domain/javascript/example.ts", { code: true, sqlite: false }], ])("selects the appropriate lanes for %s", async (path, expected) => { const { directory, base } = await fixture(); const head = await change(directory, [path]); @@ -391,6 +642,52 @@ it("scopes package script edits while retaining broad dependency checks", async }); }); +it.each(["test:sqlite", "test:sqlite:run"])( + "routes %s script changes to the SQLite runtime matrix", + async (script) => { + const { directory } = await fixture(); + const base = await change( + directory, + ["package.json"], + JSON.stringify({ scripts: { [script]: "vitest run" } }), + ); + const head = await change( + directory, + ["package.json"], + JSON.stringify({ + scripts: { [script]: "vitest run --reporter=default" }, + }), + ); + expect(await classify(directory, base, head)).toMatchObject({ + code: true, + sqlite: true, + evm: false, + package: false, + }); + }, +); + +it("keeps unrelated test script changes off the SQLite runtime matrix", async () => { + const { directory } = await fixture(); + const base = await change( + directory, + ["package.json"], + JSON.stringify({ scripts: { "test:domain": "vitest run src/domain" } }), + ); + const head = await change( + directory, + ["package.json"], + JSON.stringify({ + scripts: { "test:domain": "vitest run src/domain --reporter=default" }, + }), + ); + expect(await classify(directory, base, head)).toMatchObject({ + code: true, + sqlite: false, + evm: false, + }); +}); + it.each([ ["browser", "real-browser"], ["binary_layout", "real-binary-layout"], @@ -407,7 +704,9 @@ it.each([ async (scope, name) => { const workflow = z .object({ - on: z.object({ workflow_call: z.null() }).passthrough(), + on: z + .object({ workflow_call: z.object({}).passthrough().nullable() }) + .passthrough(), }) .parse( parse( @@ -447,8 +746,16 @@ it("rejects skipped selected work while allowing unselected lanes to skip", asyn const command = fileURLToPath( new URL("../../../scripts/ci/required.mjs", import.meta.url), ); + const { CI_FLAGS } = await loadScopes(); const jobs = { - changes: { result: "success", outputs: { evm: "true" } }, + changes: { + result: "success", + outputs: { + ...Object.fromEntries(CI_FLAGS.map((flag) => [flag, "false"])), + tier: "fast", + evm: "true", + }, + }, static: { result: "success" }, test: { result: "success" }, evm: { result: "success" }, @@ -484,7 +791,10 @@ it.each([ "src/process/capture/example.test.ts", { code: true, runtime: false, browser: false, package: false }, ], - [".nvmrc", { code: true, package: true, browser: true, evm: true }], + [ + ".nvmrc", + { code: true, package: true, browser: true, evm: true, sqlite: true }, + ], [ "tsconfig.build.json", { code: true, package: true, browser: true, evm: true }, @@ -621,8 +931,10 @@ it.each(["workflow_dispatch", "schedule"])( async (event) => { const { directory, base } = await fixture(); expect(await classify(directory, base, base, event)).toMatchObject({ + tier: "full", code: true, package: true, + sqlite: true, evm: true, browser: true, }); @@ -636,7 +948,14 @@ it("honors ci:full for successive PR revisions", async () => { for (const head of [first, second]) { expect( await classify(directory, base, head, "pull_request", true), - ).toMatchObject({ code: true, package: true, evm: true, browser: true }); + ).toMatchObject({ + tier: "full", + code: true, + package: true, + sqlite: true, + evm: true, + browser: true, + }); } }); @@ -676,7 +995,7 @@ const INTEL_HOST = { architecture: "x64", }; -it("keeps macOS x64 package verification for ci:full and non-PR events", async () => { +it("keeps macOS x64 package verification only for full qualification", async () => { const { directory, base } = await fixture(); const head = await change(directory, ["src/windows/Example.ts"]); const matrix = z.object({ include: z.array(z.unknown()) }); @@ -687,7 +1006,8 @@ it("keeps macOS x64 package verification for ci:full and non-PR events", async ( expect(pullRequest).toHaveLength(3); expect(pullRequest).not.toContainEqual(INTEL_HOST); expect(await hosts("pull_request", true)).toContainEqual(INTEL_HOST); - for (const event of ["push", "schedule", "workflow_dispatch"]) + expect(await hosts("push", false)).not.toContainEqual(INTEL_HOST); + for (const event of ["schedule", "workflow_dispatch"]) expect(await hosts(event, false)).toContainEqual(INTEL_HOST); }); @@ -700,6 +1020,7 @@ const workflowFile = async (name: string): Promise => ); const scopesSchema = z.object({ + CI_FLAGS: z.array(z.string()), SCOPES: z.record(z.string(), z.array(z.string())), MANUAL_VERIFIERS: z.array(z.string()), }); diff --git a/tests/boundary/filesystem/ciJobTimings.test.ts b/tests/boundary/filesystem/ciJobTimings.test.ts new file mode 100644 index 000000000..85a2ddd1f --- /dev/null +++ b/tests/boundary/filesystem/ciJobTimings.test.ts @@ -0,0 +1,243 @@ +import { chmod, mkdir, readFile, writeFile } from "node:fs/promises"; +import { delimiter, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +import { expect, it } from "vitest"; + +import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js"; +import { + executeWorkflowFixture, + workflowGit, +} from "../../support/workflowGit.js"; + +const reporter = fileURLToPath( + new URL("../../../scripts/ci/job-timings.mjs", import.meta.url), +); + +it("merges paginated jobs, reports elapsed metrics, and preserves raw responses", async () => { + const fixture = await createFixture([ + { + total_count: 4, + jobs: [ + { + name: "Build package", + workflow_name: "CI", + status: "completed", + conclusion: "success", + created_at: "2026-10-13T00:00:00Z", + started_at: "2026-10-13T00:00:10Z", + completed_at: "2026-10-13T00:01:10Z", + steps: [ + { + name: "Install dependencies (npm ci)", + started_at: "2026-10-13T00:00:10Z", + completed_at: "2026-10-13T00:00:40Z", + }, + { + name: "Upload artifact", + started_at: "2026-10-13T00:00:40Z", + completed_at: "2026-10-13T00:00:41Z", + }, + ], + }, + ], + }, + { + total_count: 4, + jobs: [ + { + name: "Queued lane", + status: "queued", + created_at: "2026-10-13T00:00:00Z", + started_at: "2026-10-13T00:00:00Z", + completed_at: null, + steps: [], + }, + { + name: "Running lane", + status: "in_progress", + created_at: "2026-10-13T00:00:00Z", + started_at: "2026-10-13T00:00:15Z", + completed_at: null, + steps: [ + { + name: "Download artifacts", + started_at: "2026-10-13T00:00:20Z", + completed_at: "2026-10-13T00:00:22Z", + }, + ], + }, + { + name: "Skipped lane", + status: "completed", + conclusion: "skipped", + created_at: "2026-10-13T00:00:00Z", + started_at: "2026-10-13T00:00:00Z", + completed_at: "2026-10-13T00:00:00Z", + steps: [], + }, + ], + }, + ]); + const result = await runReporter(fixture); + const report = JSON.parse( + await readFile(join(fixture.outputDirectory, "report.json"), "utf8"), + ); + + expect(report.run.snapshot).toContain("partial"); + expect(report.counts).toMatchObject({ + jobs: 4, + completed: 2, + skipped: 1, + queueUnknown: 2, + executionUnknown: 3, + completedExecutionUnknown: 0, + }); + expect(report.aggregates.queueSeconds).toMatchObject({ + count: 2, + p50: 10, + p95: 15, + }); + expect(report.aggregates.completedExecutionSeconds).toMatchObject({ + count: 1, + p50: 60, + p95: 60, + }); + expect(report.aggregates.summedCompletedJobElapsedSeconds).toMatchObject({ + value: 60, + knownCount: 1, + unknownCount: 0, + label: expect.stringContaining("not CPU time"), + }); + expect(report.jobs[1].queue).toEqual({ + seconds: null, + reason: "job start is not established by its status", + }); + expect(report.jobs[3].queue).toEqual({ + seconds: null, + reason: "job was skipped", + }); + expect(report.jobs[3].execution).toEqual({ + seconds: null, + reason: "job was skipped", + }); + expect(report.stepCosts.npmCi[0].duration.seconds).toBe(30); + expect(report.stepCosts.artifactUpload[0].duration.seconds).toBe(1); + expect(report.stepCosts.artifactDownload[0].duration.seconds).toBe(2); + expect(report.stepCostInterpretation).toContain( + "not total artifact transfer costs", + ); + expect(report.cpuSeconds).toBeUndefined(); + expect(result.stdout).toContain("4 job timing records"); + expect( + await readFile(join(fixture.outputDirectory, "jobs.json"), "utf8"), + ).toBe(fixture.raw); + const summary = await readFile(fixture.summary, "utf8"); + expect(summary).toContain("point-in-time snapshot"); + expect(summary).toContain("unknown"); + expect(summary).toContain("not CPU time"); + expect(summary).toContain("60 s"); + expect(summary).toContain("not total artifact transfer costs"); + const args = JSON.parse(await readFile(fixture.args, "utf8")); + expect(args).toEqual([ + "api", + "--paginate", + "--slurp", + "repos/example/rea/actions/runs/42/attempts/2/jobs?per_page=100", + ]); +}); + +it("marks invalid and out-of-order timestamps unknown instead of emitting negative durations", async () => { + const fixture = await createFixture([ + { + jobs: [ + { + name: "Invalid dates", + status: "completed", + created_at: "not-a-date", + started_at: "2026-10-13T00:00:10Z", + completed_at: "2026-10-13T00:00:05Z", + steps: [], + }, + ], + }, + ]); + await runReporter(fixture); + const report = JSON.parse( + await readFile(join(fixture.outputDirectory, "report.json"), "utf8"), + ); + + expect(report.jobs[0].queue).toEqual({ + seconds: null, + reason: "invalid timestamp", + }); + expect(report.jobs[0].execution).toEqual({ + seconds: null, + reason: "timestamps out of order", + }); + expect(report.counts.completedExecutionUnknown).toBe(1); + expect(report.aggregates.summedCompletedJobElapsedSeconds).toMatchObject({ + value: null, + unknownCount: 1, + }); +}); + +it("fails on malformed pages or a failed GitHub API request", async () => { + const malformed = await createFixture([{ jobs: "not-an-array" }]); + await expect(runReporter(malformed)).rejects.toThrow(); + await expect( + readFile(join(malformed.outputDirectory, "jobs.json"), "utf8"), + ).resolves.toBe(malformed.raw); + + const failedApi = await createFixture([], { exitCode: 1 }); + await expect(runReporter(failedApi)).rejects.toThrow(); +}); + +async function createFixture( + pages: unknown[], + { exitCode = 0 }: { exitCode?: number } = {}, +) { + const directory = await createTestTempDirectory("rea-ci-job-timings-"); + await workflowGit(directory, ["init", "--initial-branch=main"]); + const fakeBin = join(directory, "bin"); + await mkdir(fakeBin); + const raw = JSON.stringify(pages); + const rawPath = join(directory, "gh-response.json"); + const args = join(directory, "gh-args.json"); + await writeFile(rawPath, raw); + const fakeGh = join(fakeBin, "gh"); + await writeFile( + fakeGh, + `#!/usr/bin/env node\nconst fs = require("node:fs");\nfs.writeFileSync(process.env.CI_GH_ARGS, JSON.stringify(process.argv.slice(2)));\nprocess.stdout.write(fs.readFileSync(process.env.CI_GH_RESPONSE, "utf8"));\nprocess.exitCode = ${String(exitCode)};\n`, + ); + await chmod(fakeGh, 0o755); + const outputDirectory = join(directory, ".cache", "ci-job-timings"); + const summary = join(directory, "summary.md"); + await writeFile(summary, ""); + return { + directory, + fakeBin, + raw, + rawPath, + args, + outputDirectory, + summary, + }; +} + +function runReporter(fixture: Awaited>) { + return executeWorkflowFixture(process.execPath, [reporter], { + cwd: fixture.directory, + env: { + ...process.env, + PATH: `${fixture.fakeBin}${delimiter}${process.env.PATH ?? ""}`, + CI_REPOSITORY: "example/rea", + CI_JOB_TIMINGS_DIRECTORY: fixture.outputDirectory, + CI_GH_ARGS: fixture.args, + CI_GH_RESPONSE: fixture.rawPath, + CI_TIMING_RUN_ID: "42", + CI_TIMING_RUN_ATTEMPT: "2", + GITHUB_STEP_SUMMARY: fixture.summary, + }, + }); +} diff --git a/tests/boundary/filesystem/ciJobTimingsBatch.test.ts b/tests/boundary/filesystem/ciJobTimingsBatch.test.ts new file mode 100644 index 000000000..6c2658c00 --- /dev/null +++ b/tests/boundary/filesystem/ciJobTimingsBatch.test.ts @@ -0,0 +1,288 @@ +import { chmod, mkdir, readFile, writeFile } from "node:fs/promises"; +import { delimiter, join } from "node:path"; +import { fileURLToPath, pathToFileURL } from "node:url"; + +import { expect, it } from "vitest"; + +import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js"; +import { executeWorkflowFixture } from "../../support/workflowGit.js"; + +const batchScript = fileURLToPath( + new URL("../../../scripts/ci/job-timings-batch.mjs", import.meta.url), +); + +it("collects the latest attempt for recent completed CI and Release runs into a bounded manifest", async () => { + const recent = new Date().toISOString(); + const fixture = await createFixture([ + { + workflow_runs: [ + { + id: 42, + run_attempt: 3, + status: "completed", + conclusion: "failure", + created_at: new Date(Date.parse(recent) + 1_000).toISOString(), + }, + { + id: 41, + run_attempt: 1, + status: "completed", + conclusion: "cancelled", + created_at: recent, + }, + ], + }, + { + workflow_runs: [ + { + id: 43, + run_attempt: 2, + status: "completed", + conclusion: "success", + created_at: new Date(Date.parse(recent) + 2_000).toISOString(), + }, + ], + }, + [ + { + jobs: [ + { + name: "Release lane", + status: "completed", + conclusion: "success", + created_at: recent, + started_at: recent, + completed_at: new Date(Date.parse(recent) + 50_000).toISOString(), + steps: [], + }, + ], + }, + ], + [ + { + jobs: [ + { + name: "Failed lane", + status: "completed", + conclusion: "failure", + created_at: recent, + started_at: recent, + completed_at: new Date(Date.parse(recent) + 55_000).toISOString(), + steps: [], + }, + ], + }, + ], + [ + { + jobs: [ + { + name: "Cancelled lane", + status: "completed", + conclusion: "cancelled", + created_at: recent, + started_at: recent, + completed_at: new Date(Date.parse(recent) + 30_000).toISOString(), + steps: [], + }, + ], + }, + ], + ]); + const result = await runBatch(fixture); + const manifest = JSON.parse( + await readFile( + join(fixture.outputDirectory, "batch-manifest.json"), + "utf8", + ), + ); + const calls = JSON.parse(await readFile(fixture.calls, "utf8")); + + expect(result.stdout).toContain("3 collected runs"); + expect( + await readFile(join(fixture.directory, "summary.md"), "utf8"), + ).toContain("collected 3 of 3"); + expect(manifest.selection).toMatchObject({ + lookbackHours: 24, + maxRunsPerWorkflow: 100, + exhaustive: false, + }); + expect(manifest.coverage).toMatchObject({ + workflowsQueried: ["CI", "Release"], + selectedRuns: 3, + collectedRuns: 3, + }); + expect(manifest.truncation).toEqual([]); + expect(manifest.errors).toEqual([]); + expect(manifest.runs).toMatchObject([ + { id: 43, runAttempt: 2, conclusion: "success" }, + { id: 42, runAttempt: 3, conclusion: "failure" }, + { id: 41, runAttempt: 1, conclusion: "cancelled" }, + ]); + expect(manifest.runs).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + status: "collected", + rawPath: expect.any(String), + reportPath: expect.any(String), + }), + ]), + ); + expect(calls).toContainEqual([ + "api", + "--paginate", + "--slurp", + "repos/example/rea/actions/runs/42/attempts/3/jobs?per_page=100", + ]); + expect(calls).toContainEqual([ + "api", + "--paginate", + "--slurp", + "repos/example/rea/actions/runs/41/attempts/1/jobs?per_page=100", + ]); + const failedReport = JSON.parse( + await readFile( + join(fixture.outputDirectory, "runs/42-3/report.json"), + "utf8", + ), + ); + expect(failedReport.jobs[0].conclusion).toBe("failure"); + expect(failedReport.jobs[0].execution.seconds).toBe(55); +}); + +it("records listing and per-run errors without claiming complete coverage", async () => { + const recent = new Date().toISOString(); + const fixture = await createFixture([ + { + workflow_runs: [ + { + id: 7, + run_attempt: 2, + status: "completed", + conclusion: "success", + created_at: recent, + }, + ], + }, + { error: true }, + { jobs: "malformed" }, + ]); + await runBatch(fixture); + const manifest = JSON.parse( + await readFile( + join(fixture.outputDirectory, "batch-manifest.json"), + "utf8", + ), + ); + expect(manifest.selection.exhaustive).toBe(false); + expect(manifest.errors).toMatchObject([ + { scope: "workflow:Release" }, + { scope: "run" }, + ]); + expect(manifest.runs[0]).toMatchObject({ + id: 7, + runAttempt: 2, + status: "error", + }); +}); + +it("retains a partial manifest when its collection budget is exhausted", async () => { + const fixture = await createFixture([ + { + workflow_runs: [8, 9].map((id) => ({ + id, + run_attempt: 1, + status: "completed", + created_at: new Date().toISOString(), + })), + }, + { workflow_runs: [] }, + ]); + await executeWorkflowFixture( + process.execPath, + [ + "--input-type=module", + "-e", + ` + const { collectJobTimingsBatch } = await import(${JSON.stringify(pathToFileURL(batchScript).href)}); + let clock = Date.now(); + await collectJobTimingsBatch({ + repository: "example/rea", + outputDirectory: process.env.CI_JOB_TIMINGS_DIRECTORY, + now: () => clock, + collect: async () => { + clock += 240001; + throw new Error("fixture request exhausted the remaining budget"); + }, + }); + `, + ], + { cwd: fixture.directory, env: fixtureEnvironment(fixture) }, + ); + const manifest = JSON.parse( + await readFile( + join(fixture.outputDirectory, "batch-manifest.json"), + "utf8", + ), + ); + expect(manifest.coverage).toMatchObject({ + selectedRuns: 2, + collectedRuns: 0, + }); + expect(manifest.runs).toHaveLength(1); + expect(manifest.runs[0]).toMatchObject({ status: "error" }); + expect(manifest.truncation.join(" ")).toContain("Time budget"); +}); + +async function createFixture(responses: unknown[]) { + const directory = await createTestTempDirectory("rea-ci-job-timings-batch-"); + const fakeBin = join(directory, "bin"); + await mkdir(fakeBin); + const responsePath = join(directory, "responses.json"); + const calls = join(directory, "calls.json"); + await writeFile(responsePath, JSON.stringify(responses)); + await writeFile(calls, "[]"); + const fakeGh = join(fakeBin, "gh"); + await writeFile( + fakeGh, + `#!/usr/bin/env node +const fs = require("node:fs"); +const calls = JSON.parse(fs.readFileSync(process.env.CI_GH_CALLS, "utf8")); +calls.push(process.argv.slice(2)); +fs.writeFileSync(process.env.CI_GH_CALLS, JSON.stringify(calls)); +const responses = JSON.parse(fs.readFileSync(process.env.CI_GH_RESPONSES, "utf8")); +const response = responses[calls.length - 1]; +if (response && response.error) { process.stderr.write("fixture API error"); process.exitCode = 1; } +else process.stdout.write(JSON.stringify(response)); +`, + ); + await chmod(fakeGh, 0o755); + return { + directory, + fakeBin, + responses: responsePath, + calls, + outputDirectory: join(directory, ".cache", "ci-job-timings"), + }; +} + +function runBatch(fixture: Awaited>) { + return executeWorkflowFixture(process.execPath, [batchScript], { + cwd: fixture.directory, + env: fixtureEnvironment(fixture), + }); +} + +function fixtureEnvironment( + fixture: Awaited>, +) { + return { + ...process.env, + PATH: `${fixture.fakeBin}${delimiter}${process.env.PATH ?? ""}`, + CI_REPOSITORY: "example/rea", + CI_JOB_TIMINGS_DIRECTORY: fixture.outputDirectory, + CI_GH_CALLS: fixture.calls, + CI_GH_RESPONSES: fixture.responses, + GITHUB_STEP_SUMMARY: join(fixture.directory, "summary.md"), + }; +} diff --git a/tests/boundary/filesystem/ciPrEvents.test.ts b/tests/boundary/filesystem/ciPrEvents.test.ts new file mode 100644 index 000000000..3562b5df9 --- /dev/null +++ b/tests/boundary/filesystem/ciPrEvents.test.ts @@ -0,0 +1,98 @@ +import { readFile } from "node:fs/promises"; +import { expect, it } from "vitest"; +import { parse } from "yaml"; +import { z } from "zod"; +import { executeWorkflowFixture } from "../../support/workflowGit.js"; + +async function workflow(name: string) { + return z + .object({ + on: z.record(z.string(), z.unknown()), + permissions: z.record(z.string(), z.string()), + concurrency: z.object({ group: z.string() }).optional(), + jobs: z.record( + z.string(), + z.object({ + name: z.string().optional(), + if: z.string().optional(), + uses: z.string().optional(), + with: z.record(z.string(), z.string()).optional(), + steps: z + .array( + z.object({ + run: z.string().optional(), + uses: z.string().optional(), + env: z.record(z.string(), z.string()).optional(), + }), + ) + .optional(), + }), + ), + }) + .parse( + parse( + await readFile( + new URL(`../../../.github/workflows/${name}`, import.meta.url), + "utf8", + ), + ), + ); +} + +it("refreshes title validation on edits without checking out PR code or cancelling CI", async () => { + const title = await workflow("pr-title.yml"); + expect(title.on.pull_request).toMatchObject({ + types: ["opened", "synchronize", "reopened", "edited"], + }); + expect(title.permissions).toEqual({}); + expect(title.concurrency?.group).not.toBe( + (await workflow("ci.yml")).concurrency?.group, + ); + const jobs = Object.values(title.jobs); + expect(jobs).toHaveLength(1); + expect(jobs[0]?.name).toBe("Conventional PR title"); + expect(jobs[0]?.if).toBeUndefined(); // A skipped check must not green-light an invalid title on body edits. + const steps = jobs[0]?.steps ?? []; + expect(steps).toHaveLength(1); + expect(steps[0]?.uses).toBeUndefined(); + expect(steps[0]?.env).toEqual({ + PR_TITLE: "${{ github.event.pull_request.title }}", + }); + const command = z.string().parse(steps[0]?.run); + for (const title of [ + "fix(ci): repair workflow", + "feat!: changed contract", + "docs: literal $(exit 91) `exit 92` text", + ]) { + await expect( + executeWorkflowFixture("bash", ["-c", command], { + env: { ...process.env, PR_TITLE: title }, + }), + ).resolves.toMatchObject({ stderr: "" }); + } + for (const title of ["", "Fix CI", "feat: "]) { + await expect( + executeWorkflowFixture("bash", ["-c", command], { + env: { ...process.env, PR_TITLE: title }, + }), + ).rejects.toMatchObject({ code: 1 }); + } + expect((await workflow("ci.yml")).jobs["pr-title"]).toBeUndefined(); +}); + +it("qualifies only ci:full label additions at the caller's merge revision", async () => { + const full = await workflow("ci-full-pr.yml"); + expect(full.on.pull_request).toMatchObject({ types: ["labeled"] }); + expect(full.permissions).toEqual({ contents: "read", actions: "read" }); + expect(Object.values(full.jobs)).toEqual([ + { + name: "Qualify labeled PR revision", + if: "github.event.label.name == 'ci:full'", + uses: "./.github/workflows/ci.yml", + with: { source_sha: "${{ github.sha }}" }, + }, + ]); + // Metadata events must not create skipped replacements for the main CI checks. + expect(full.jobs.required).toBeUndefined(); + expect(full.concurrency).toBeUndefined(); +}); diff --git a/tests/boundary/filesystem/ciQualification.test.ts b/tests/boundary/filesystem/ciQualification.test.ts new file mode 100644 index 000000000..b6a5a1e1a --- /dev/null +++ b/tests/boundary/filesystem/ciQualification.test.ts @@ -0,0 +1,375 @@ +import { chmod, mkdir, readFile, writeFile } from "node:fs/promises"; +import { join } from "node:path"; +import { fileURLToPath } from "node:url"; + +import { expect, it } from "vitest"; +import { parse } from "yaml"; +import { z } from "zod"; + +import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js"; +import { + executeWorkflowFixture, + workflowGit, +} from "../../support/workflowGit.js"; + +const qualificationScript = fileURLToPath( + new URL("../../../scripts/ci/qualification.mjs", import.meta.url), +); +const requiredScript = fileURLToPath( + new URL("../../../scripts/ci/required.mjs", import.meta.url), +); +const now = Date.now(); +const validSha = "a".repeat(40); +const repository = "example/rea"; + +function artifact(overrides: Record = {}) { + return { + id: 42, + name: "ci-full-qualification-v1", + expired: false, + created_at: new Date(now - 60_000).toISOString(), + workflow_run: { + id: 7, + repository_id: 1, + head_repository_id: 1, + head_branch: "main", + head_sha: validSha, + }, + ...overrides, + }; +} + +function run(overrides: Record = {}) { + return { + id: 7, + status: "completed", + conclusion: "success", + path: ".github/workflows/ci.yml", + event: "schedule", + created_at: new Date(now - 120_000).toISOString(), + head_sha: validSha, + head_branch: "main", + head_repository: { full_name: repository }, + ...overrides, + }; +} + +async function admissionFixture( + candidate: Record = artifact(), + candidateRun: Record = run(), + options: { apiError?: boolean; malformed?: boolean; force?: boolean } = {}, +) { + const directory = await createTestTempDirectory("rea-ci-qualification-"); + const bin = join(directory, "bin"); + await mkdir(bin); + const fixturePath = join(directory, "api.json"); + await writeFile( + fixturePath, + options.malformed + ? "not-json" + : JSON.stringify({ artifacts: [candidate], run: candidateRun }), + ); + const gh = join(bin, "gh"); + await writeFile( + gh, + [ + "#!/bin/sh", + 'if [ "$GH_API_ERROR" = "true" ]; then exit 1; fi', + 'case "$*" in', + ' *actions/artifacts*) cat "$GH_FIXTURE_RESPONSE" ;;', + " *actions/runs/7*) node -e 'const x=require(process.env.GH_FIXTURE_RESPONSE); process.stdout.write(JSON.stringify(x.run))' ;;", + " *) exit 2 ;;", + "esac", + "", + ].join("\n"), + ); + await chmod(gh, 0o755); + const output = join(directory, "github-output"); + await writeFile(output, ""); + const env = { + ...process.env, + PATH: `${bin}:${process.env.PATH ?? ""}`, + GH_FIXTURE_RESPONSE: fixturePath, + GH_API_ERROR: String(options.apiError ?? false), + CI_REPOSITORY: repository, + CI_REPOSITORY_ID: "1", + CI_DEFAULT_BRANCH: "main", + HEAD_SHA: validSha, + GITHUB_RUN_ID: "100", + GITHUB_OUTPUT: output, + ...(options.force ? { CI_FORCE_FULL: "true" } : {}), + }; + return { directory, output, env }; +} + +async function decide( + candidate?: Record, + candidateRun?: Record, + options?: { apiError?: boolean; malformed?: boolean; force?: boolean }, +) { + const fixture = await admissionFixture(candidate, candidateRun, options); + const result = await executeWorkflowFixture( + process.execPath, + [qualificationScript], + { + cwd: fixture.directory, + env: fixture.env, + }, + ); + return { + ...fixture, + decision: z + .record(z.string(), z.unknown()) + .parse(JSON.parse(result.stdout)), + outputText: await readFile(fixture.output, "utf8"), + }; +} + +it("reuses only a recent trusted full qualification for the exact default-branch SHA", async () => { + const { decision, outputText } = await decide(); + expect(decision).toMatchObject({ run_full: false, run_id: 7 }); + expect(Object.keys(decision).sort()).toEqual([ + "reason", + "run_full", + "run_id", + ]); + expect(outputText).toContain("run_full=false\n"); + expect(outputText).toContain("run_id=7\n"); +}); + +const rejectedCandidates: Array< + [string, () => Record, () => Record] +> = [ + [ + "old", + () => + artifact({ + created_at: new Date(now - 24 * 60 * 60 * 1000 - 1).toISOString(), + }), + run, + ], + [ + "future", + () => artifact({ created_at: new Date(now + 60_000).toISOString() }), + run, + ], + ["expired", () => artifact({ expired: true }), run], + [ + "foreign repository", + () => + artifact({ + workflow_run: { ...artifact().workflow_run, repository_id: 2 }, + }), + run, + ], + [ + "foreign branch", + () => + artifact({ + workflow_run: { ...artifact().workflow_run, head_branch: "other" }, + }), + run, + ], + [ + "foreign SHA", + () => + artifact({ + workflow_run: { ...artifact().workflow_run, head_sha: "b".repeat(40) }, + }), + run, + ], + [ + "untrusted workflow", + artifact, + () => run({ path: ".github/workflows/release.yml" }), + ], + ["failed run", artifact, () => run({ conclusion: "failure" })], + [ + "old producer rerun with a fresh artifact", + artifact, + () => + run({ created_at: new Date(now - 25 * 60 * 60 * 1000).toISOString() }), + ], + ["wrong workflow event", artifact, () => run({ event: "push" })], +]; + +it.each(rejectedCandidates)( + "runs full qualification for a %s candidate", + async (_name, makeArtifact, makeRun) => { + const { decision } = await decide(makeArtifact(), makeRun()); + expect(decision.run_full).toBe(true); + }, +); + +it.each([ + ["API error", { apiError: true }], + ["malformed query response", { malformed: true }], +] as const)("fails closed on %s", async (_name, options) => { + const { decision } = await decide(undefined, undefined, options); + expect(decision.run_full).toBe(true); +}); + +it("lets the daily force-full setting bypass the GitHub API", async () => { + const { decision } = await decide(undefined, undefined, { + force: true, + apiError: true, + }); + expect(decision).toMatchObject({ run_full: true }); + expect(decision.reason).toContain("Forced"); +}); + +async function workflowContract() { + const workflowPath = new URL( + "../../../.github/workflows/ci.yml", + import.meta.url, + ); + const parsed = parse(await readFile(workflowPath, "utf8")); + return z + .object({ + jobs: z.record( + z.string(), + z.object({ needs: z.unknown().optional() }).passthrough(), + ), + }) + .parse(parsed).jobs; +} + +async function requiredRun( + changes: Record, + overrides: { failed?: string; runAttempt?: string; event?: string } = {}, +) { + const directory = await createTestTempDirectory("rea-ci-receipt-"); + await workflowGit(directory, ["init", "--initial-branch=main"]); + await writeFile(join(directory, "fixture.txt"), "qualified source\n"); + await workflowGit(directory, ["add", "."]); + await workflowGit(directory, ["commit", "-m", "fixture source"]); + const head = await workflowGit(directory, ["rev-parse", "HEAD"]); + const jobs = await workflowContract(); + const results: Record< + string, + { result: string; outputs?: Record } + > = {}; + for (const name of z.array(z.string()).parse(jobs.required?.needs)) { + results[name] = { + result: + name === overrides.failed + ? "failure" + : changes.tier === "reused" + ? "skipped" + : "success", + }; + } + results.changes = { result: "success", outputs: changes }; + const receiptDirectory = join(directory, ".cache", "receipt"); + const output = join(directory, "github-output"); + await writeFile(output, ""); + const env = { + ...process.env, + CI_JOBS: JSON.stringify(results), + CI_QUALIFICATION_DIRECTORY: receiptDirectory, + GITHUB_EVENT_NAME: overrides.event ?? "schedule", + GITHUB_SHA: head, + GITHUB_RUN_ID: "100", + GITHUB_RUN_ATTEMPT: overrides.runAttempt ?? "1", + GITHUB_REPOSITORY: repository, + GITHUB_OUTPUT: output, + }; + const result = executeWorkflowFixture(process.execPath, [requiredScript], { + cwd: directory, + env, + }); + return { directory, head, output, result }; +} + +it("writes a full receipt only after every canonical flag and workflow need pass", async () => { + const scopesPath = new URL("../../../scripts/ci/scopes.mjs", import.meta.url); + const { CI_FLAGS } = await import(scopesPath.href); + const changes = Object.fromEntries( + CI_FLAGS.map((flag: string) => [flag, "true"]), + ); + changes.tier = "full"; + const { directory, head, output, result } = await requiredRun(changes); + await expect(result).resolves.toMatchObject({ stderr: "" }); + const receiptPath = join(directory, ".cache", "receipt", "receipt.json"); + const receipt = z + .object({ + sourceSha: z.string(), + runId: z.number(), + runAttempt: z.number(), + }) + .parse(JSON.parse(await readFile(receiptPath, "utf8"))); + expect(receipt).toMatchObject({ sourceSha: head, runId: 100, runAttempt: 1 }); + expect(await readFile(output, "utf8")).toContain( + `receipt_path=${receiptPath}\n`, + ); + expect(await readFile(output, "utf8")).toContain( + "receipt_name=ci-full-qualification-v1\n", + ); +}); + +it.each([ + ["failed selected lane", { failed: "sqlite-runtime" }], + ["partial full scope", {}], +] as const)( + "does not issue a receipt after %s", + async (caseName, overrides) => { + const scopesPath = new URL( + "../../../scripts/ci/scopes.mjs", + import.meta.url, + ); + const { CI_FLAGS } = await import(scopesPath.href); + const changes = Object.fromEntries( + CI_FLAGS.map((flag: string) => [flag, "true"]), + ); + changes.tier = "full"; + if (caseName === "partial full scope") changes.sqlite = "false"; + const outcome = await requiredRun(changes, overrides); + await expect(outcome.result).rejects.toMatchObject({ code: 1 }); + await expect( + readFile(join(outcome.directory, ".cache", "receipt", "receipt.json")), + ).rejects.toMatchObject({ code: "ENOENT" }); + expect(await readFile(outcome.output, "utf8")).not.toContain("receipt_"); + }, +); + +it("never writes a fresh receipt for a reused scheduled qualification", async () => { + const scopesPath = new URL("../../../scripts/ci/scopes.mjs", import.meta.url); + const { CI_FLAGS } = await import(scopesPath.href); + const changes = Object.fromEntries( + CI_FLAGS.map((flag: string) => [flag, "false"]), + ); + changes.tier = "reused"; + changes.qualification_run_id = "7"; + const outcome = await requiredRun(changes); + const result = await outcome.result; + await expect( + readFile(join(outcome.directory, ".cache", "receipt", "receipt.json")), + ).rejects.toMatchObject({ code: "ENOENT" }); + expect(result.stdout).toContain("Qualification reused from run 7"); + expect(await readFile(outcome.output, "utf8")).not.toContain("receipt_"); +}); + +it.each([ + ["missing receipt run", { qualification_run_id: "" }, "schedule"], + ["selected validation lane", { sqlite: "true" }, "schedule"], + ["manual dispatch", {}, "workflow_dispatch"], +] as const)( + "rejects qualification reuse with %s", + async (_name, override, event) => { + const { CI_FLAGS } = await import( + new URL("../../../scripts/ci/scopes.mjs", import.meta.url).href + ); + const changes: Record = { + ...Object.fromEntries(CI_FLAGS.map((flag: string) => [flag, "false"])), + tier: "reused", + qualification_run_id: "7", + ...override, + }; + const outcome = await requiredRun(changes, { event }); + await expect(outcome.result).rejects.toMatchObject({ + code: 1, + stderr: expect.stringContaining("scheduled admission receipt"), + }); + expect(await readFile(outcome.output, "utf8")).not.toContain("receipt_"); + }, +); diff --git a/tests/boundary/filesystem/ciRequiredLanes.test.ts b/tests/boundary/filesystem/ciRequiredLanes.test.ts index 4cff44e96..b6e02b54a 100644 --- a/tests/boundary/filesystem/ciRequiredLanes.test.ts +++ b/tests/boundary/filesystem/ciRequiredLanes.test.ts @@ -26,7 +26,19 @@ const workflow = async (filename = "ci.yml") => ), ); +const scopeFlags = async () => + z + .object({ CI_FLAGS: z.array(z.string()) }) + .parse( + await import( + new URL("../../../scripts/ci/scopes.mjs", import.meta.url).href + ), + ).CI_FLAGS; + it("binds SQLite compatibility jobs to the build's prepared runtime artifact and root layout", async () => { + expect((await workflow()).jobs["sqlite-runtime"]?.if).toBe( + "needs.changes.outputs.sqlite == 'true'", + ); const steps = z.array( z.object({ uses: z.string().optional(), @@ -52,6 +64,77 @@ it("binds SQLite compatibility jobs to the build's prepared runtime artifact and expect(downloads[0]?.with).toEqual({ name, path: "." }); }); +it("exports every canonical scope with read authority for admission and keeps telemetry outside the gate", async () => { + const { jobs } = await workflow(); + const CI_FLAGS = await scopeFlags(); + const outputs = z.record(z.string(), z.string()).parse(jobs.changes?.outputs); + expect(jobs.changes?.permissions).toEqual({ + contents: "read", + actions: "read", + }); + expect(jobs.build?.permissions).toEqual({ + contents: "read", + actions: "read", + }); + for (const flag of CI_FLAGS) + expect(outputs[flag]).toBe(`\${{ steps.plan.outputs.${flag} }}`); + const steps = z + .array( + z.object({ + run: z.string().optional(), + if: z.string().optional(), + }), + ) + .parse(jobs.required?.steps); + const telemetry = steps.find((step) => + step.run?.includes("scripts/ci/job-timings.mjs"), + ); + expect(telemetry).toBeUndefined(); + const timings = z + .object({ + on: z.object({ + schedule: z.array(z.object({ cron: z.string() })), + workflow_dispatch: z.unknown(), + workflow_run: z.unknown().optional(), + }), + permissions: z.record(z.string(), z.string()), + jobs: z.object({ + report: z.object({ + steps: z.array( + z.object({ + uses: z.string().optional(), + run: z.string().optional(), + with: z.record(z.string(), z.unknown()).optional(), + env: z.record(z.string(), z.unknown()).optional(), + }), + ), + }), + }), + }) + .parse( + parse( + await readFile( + new URL("../../../.github/workflows/ci-timings.yml", import.meta.url), + "utf8", + ), + ), + ); + expect(timings.on.workflow_run).toBeUndefined(); + expect(timings.on.schedule).toHaveLength(1); + expect(timings.permissions).toEqual({ contents: "read", actions: "read" }); + const checkout = timings.jobs.report.steps.find((step) => + step.uses?.startsWith("actions/checkout@"), + ); + expect(checkout?.with).toEqual({ + ref: "${{ github.event.repository.default_branch }}", + "persist-credentials": false, + }); + const report = timings.jobs.report.steps.find((step) => + step.run?.includes("scripts/ci/job-timings-batch.mjs"), + ); + expect(report?.env?.CI_REPOSITORY).toBe("${{ github.repository }}"); +}); + const requiredNeeds = async () => { const { jobs } = await workflow(); return { jobs, needs: z.array(z.string()).parse(jobs.required?.needs) }; @@ -64,6 +147,240 @@ it("makes the required gate wait for every CI lane, including future additions", ); }); +it("holds native and provider fan-out behind static validation while portable feedback stays independent", async () => { + const { jobs } = await workflow(); + const earlyJobs = new Set([ + "changes", + "static", + "build", + "test-shard", + "test", + "docs", + "required", + ]); + for (const [name, job] of Object.entries(jobs)) { + if (earlyJobs.has(name)) continue; + expect(job.needs, `${name} must wait for static validation`).toContain( + "static", + ); + expect(job.if).not.toMatch(/always\(|cancelled\(/u); + } + expect(jobs["test-shard"]?.needs).not.toContain("static"); +}); + +it("binds provider build reuse to the current run while keeping standalone dispatches independent", async () => { + const { jobs } = await workflow(); + const consumers = [ + "browser", + "binary_layout", + "evm", + "javascript_recovery", + "recorded_crash", + "web_network", + "web_runtime", + "web_source_map", + ]; + const buildTerms = z + .string() + .parse(jobs.build?.if) + .split("||") + .map((term) => term.trim()); + // Provider workflow edits select their lane without code=true. The build + // producer must still run, without selecting the portable test shards. + expect(new Set(buildTerms)).toEqual( + new Set( + ["code", ...consumers].map( + (scope) => `needs.changes.outputs.${scope} == 'true'`, + ), + ), + ); + expect(jobs["test-shard"]?.if).toBe("needs.changes.outputs.code == 'true'"); + for (const name of consumers) { + const caller = jobs[name]; + expect(caller?.needs).toContain("build"); + expect(caller?.with).toEqual({ build_cache_artifact: "rea-build-cache" }); + const path = z.string().parse(caller?.uses); + const called = z + .object({ + on: z.object({ + workflow_call: z.object({ + inputs: z.record(z.string(), z.unknown()), + }), + workflow_dispatch: z.unknown(), + }), + jobs: z.record( + z.string(), + z.object({ + steps: z.array( + z.object({ + uses: z.string().optional(), + with: z.record(z.string(), z.unknown()).optional(), + }), + ), + }), + ), + }) + .parse( + parse( + await readFile(new URL(`../../../${path}`, import.meta.url), "utf8"), + ), + ); + expect(called.on.workflow_call.inputs.build_cache_artifact).toMatchObject({ + type: "string", + default: "", + }); + expect(Object.hasOwn(called.on, "workflow_dispatch")).toBe(true); + for (const job of Object.values(called.jobs)) + expect( + job.steps.find( + (step) => step.uses === "./.github/actions/portable-build-cache", + )?.with, + ).toEqual({ build_cache_artifact: "${{ inputs.build_cache_artifact }}" }); + } + const action = z + .object({ + runs: z.object({ + steps: z.array( + z.object({ + id: z.string().optional(), + uses: z.string().optional(), + if: z.string().optional(), + with: z.record(z.string(), z.unknown()).optional(), + "continue-on-error": z.boolean().optional(), + }), + ), + }), + }) + .parse( + parse( + await readFile( + new URL( + "../../../.github/actions/portable-build-cache/action.yml", + import.meta.url, + ), + "utf8", + ), + ), + ); + const download = action.runs.steps.find( + (step) => step.uses === "actions/download-artifact@v4", + ); + expect(download?.with).toEqual({ + name: "${{ inputs.build_cache_artifact }}", + path: ".turbo/cache/", + }); + expect(download?.if).toBe("inputs.build_cache_artifact != ''"); + expect(download?.["continue-on-error"]).not.toBe(true); + for (const step of action.runs.steps.filter( + (step) => step.id === "plan" || step.uses?.startsWith("actions/cache"), + )) + expect(step.if).toContain("inputs.build_cache_artifact == ''"); +}); + +it("runs workflow validation inside required static checks when selected", async () => { + const { jobs } = await workflow(); + const steps = z + .array(z.object({ run: z.string().optional(), if: z.string().optional() })) + .parse(jobs.static?.steps); + const validation = steps.filter((step) => step.run?.includes("actionlint")); + expect(validation).toHaveLength(1); + expect(validation[0]?.if).toBe("needs.changes.outputs.workflows == 'true'"); + expect(jobs.workflows).toBeUndefined(); +}); + +it("leaves cancellation ownership with CI so child lanes cannot cancel another tier", async () => { + const { jobs } = await workflow(); + const children = Object.values(jobs).flatMap((job) => + typeof job.uses === "string" && job.uses.startsWith("./.github/workflows/") + ? [job.uses] + : [], + ); + expect(children.length).toBeGreaterThan(0); + for (const path of children) { + const child = z + .object({ concurrency: z.unknown().optional() }) + .parse( + parse( + await readFile(new URL(`../../../${path}`, import.meta.url), "utf8"), + ), + ); + expect( + child.concurrency, + `${path} must use caller scheduling`, + ).toBeUndefined(); + } +}); + +it("keeps fast feedback separate from complete qualification and release proof", async () => { + const ci = z + .object({ + on: z.object({ + push: z.unknown(), + pull_request: z.unknown(), + schedule: z.array(z.object({ cron: z.string() })), + workflow_call: z.object({ + inputs: z.object({ + source_sha: z.object({ + required: z.literal(true), + type: z.literal("string"), + }), + }), + }), + }), + concurrency: z.object({ + group: z.string(), + "cancel-in-progress": z.string(), + }), + jobs: z.record( + z.string(), + z.object({ + if: z.string().optional(), + steps: z + .array( + z.object({ + run: z.string().optional(), + if: z.string().optional(), + with: z.record(z.string(), z.unknown()).optional(), + }), + ) + .optional(), + }), + ), + }) + .parse( + parse( + await readFile( + new URL("../../../.github/workflows/ci.yml", import.meta.url), + "utf8", + ), + ), + ); + expect(ci.on.schedule).toEqual([ + { cron: "23 0-2,4-23 * * *" }, + { cron: "23 3 * * *" }, + ]); + expect(ci.concurrency.group).toContain("'qualification' || 'feedback'"); + expect(ci.concurrency.group).toContain("inputs.source_sha ||"); + expect(ci.concurrency.group).toContain("github.ref"); + expect(ci.concurrency["cancel-in-progress"]).toBe( + "${{ github.event_name == 'pull_request' && inputs.source_sha == '' && !contains(github.event.pull_request.labels.*.name, 'ci:full') }}", + ); + expect(ci.jobs.required?.if).toBe("${{ always() }}"); + const shards = ci.jobs["test-shard"]?.steps ?? []; + const fast = shards.find((step) => step.run?.includes("npm run test:run")); + const full = shards.find((step) => step.run?.includes("test:ci:shard:run")); + expect(fast?.if).toBe("needs.changes.outputs.tier == 'fast'"); + expect(fast?.run).toContain("--reporter=blob"); + expect(fast?.run).not.toContain("--coverage"); + expect(full?.if).toBe("needs.changes.outputs.tier == 'full'"); + const proof = ci.jobs["package-e2e"]?.steps?.find( + (step) => step.with?.name === "verified-release-package", + ); + expect(proof?.if).toContain("needs.changes.outputs.tier == 'full'"); + expect(proof?.if).toContain("matrix.platform == 'linux'"); + expect(proof?.if).toContain("matrix.architecture == 'x64'"); +}); + it.each([ ["true", "success", true], ["true", "failure", false], @@ -71,34 +388,119 @@ it.each([ ["true", "skipped", false], ["true", "missing", false], ["false", "skipped", true], + ["false", "failure", false], ] as const)( - "enforces the SQLite required gate for code=%s and result=%s", - async (code, result, passes) => { + "enforces mapped required scopes for selected=%s and result=%s", + async (selected, result, passes) => { const workflow = await requiredNeeds(); - // GitHub exposes only direct dependencies in the required job's needs context. - const needs: Record< - string, - { result: string; outputs?: Record } - > = Object.fromEntries( - workflow.needs.map((name) => [name, { result: "success" }]), - ); - needs.changes = { result: "success", outputs: { code } }; - if (result === "missing") delete needs["sqlite-runtime"]; - else if ("sqlite-runtime" in needs) needs["sqlite-runtime"] = { result }; - const execution = executeWorkflowFixture( + for (const [scope, lane] of [ + ["sqlite", "sqlite-runtime"], + ["workflows", "static"], + ] as const) { + // GitHub exposes only direct dependencies in the required job's needs context. + const needs: Record< + string, + { result: string; outputs?: Record } + > = Object.fromEntries( + workflow.needs.map((name) => [name, { result: "success" }]), + ); + needs.changes = { + result: "success", + outputs: { + ...Object.fromEntries( + (await scopeFlags()).map((flag) => [flag, "false"]), + ), + tier: "fast", + code: "true", + [scope]: selected, + }, + }; + if (result === "missing") delete needs[lane]; + else needs[lane] = { result }; + const execution = executeWorkflowFixture( + process.execPath, + [ + fileURLToPath( + new URL("../../../scripts/ci/required.mjs", import.meta.url), + ), + ], + { env: { ...process.env, CI_JOBS: JSON.stringify(needs) } }, + ); + // Static checks remain required even without workflow edits. + const expected = passes && !(lane === "static" && result !== "success"); + if (expected) + await expect(execution).resolves.toMatchObject({ stderr: "" }); + else + await expect(execution).rejects.toMatchObject({ + code: 1, + stderr: expect.stringContaining(lane), + }); + } + }, +); + +it("rejects incomplete or malformed classification even when available jobs succeeded", async () => { + const flags = await scopeFlags(); + const valid = { + ...Object.fromEntries(flags.map((flag) => [flag, "false"])), + tier: "fast", + }; + const run = (outputs: unknown) => + executeWorkflowFixture( process.execPath, [ fileURLToPath( new URL("../../../scripts/ci/required.mjs", import.meta.url), ), ], - { env: { ...process.env, CI_JOBS: JSON.stringify(needs) } }, + { + env: { + ...process.env, + CI_JOBS: JSON.stringify({ + changes: { result: "success", outputs }, + static: { result: "success" }, + test: { result: "success" }, + }), + CI_QUALIFICATION_DIRECTORY: "", + }, + }, ); - if (passes) await expect(execution).resolves.toMatchObject({ stderr: "" }); - else - await expect(execution).rejects.toMatchObject({ - code: 1, - stderr: expect.stringContaining("sqlite-runtime"), - }); - }, -); + await expect(run(valid)).resolves.toMatchObject({ stderr: "" }); + // Metadata is not a scope, even when its string happens to be "true". + await expect( + run({ ...valid, qualification_run_id: "true" }), + ).resolves.toMatchObject({ stderr: "" }); + for (const outputs of [ + undefined, + null, + {}, + { ...valid, tier: undefined }, + { ...valid, tier: "" }, + { ...valid, tier: "unknown" }, + ]) { + await expect(run(outputs)).rejects.toMatchObject({ + code: 1, + stderr: expect.stringContaining("valid tier"), + }); + } + for (const flag of flags) { + await expect(run({ ...valid, [flag]: undefined })).rejects.toMatchObject({ + code: 1, + stderr: expect.stringContaining(`scope outputs: ${flag}`), + }); + } + for (const value of ["", "TRUE", "yes", true, false, 0, null, [], {}]) { + await expect(run({ ...valid, sqlite: value })).rejects.toMatchObject({ + code: 1, + stderr: expect.stringContaining("scope outputs: sqlite"), + }); + } + for (const tier of ["full", "reused"]) { + await expect( + run({ ...valid, tier, sqlite: undefined }), + ).rejects.toMatchObject({ + code: 1, + stderr: expect.stringContaining("scope outputs: sqlite"), + }); + } +}); diff --git a/tests/boundary/filesystem/ciTestHistory.test.ts b/tests/boundary/filesystem/ciTestHistory.test.ts new file mode 100644 index 000000000..411e9ece9 --- /dev/null +++ b/tests/boundary/filesystem/ciTestHistory.test.ts @@ -0,0 +1,188 @@ +import { chmod, mkdir, readFile, writeFile } from "node:fs/promises"; +import { delimiter, dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +import { expect, it } from "vitest"; + +import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js"; +import { executeWorkflowFixture } from "../../support/workflowGit.js"; + +const script = fileURLToPath( + new URL("../../../scripts/ci/test-history.mjs", import.meta.url), +); +const repository = "example/rea"; +const repositoryId = 1; +const now = Date.now(); + +function artifact(id: number, overrides: Record = {}) { + return { + id: id + 100, + name: "test-timings", + expired: false, + created_at: new Date(now - 60_000).toISOString(), + workflow_run: { + id, + repository_id: repositoryId, + head_repository_id: repositoryId, + head_branch: "main", + }, + ...overrides, + }; +} + +function run(id: number, overrides: Record = {}) { + return { + id, + status: "completed", + conclusion: "success", + path: ".github/workflows/ci.yml", + event: "schedule", + created_at: new Date(now - 120_000).toISOString(), + head_branch: "main", + head_repository: { full_name: repository }, + ...overrides, + }; +} + +async function invoke( + artifacts: unknown[], + runs: Record, + options: { + apiError?: boolean; + repository?: string; + repositoryId?: string; + } = {}, +) { + const directory = await createTestTempDirectory("rea-ci-test-history-"); + const fakeBin = join(directory, "bin"); + await mkdir(fakeBin); + const fixture = join(directory, "api.json"); + const calls = join(directory, "api-calls"); + const output = join(directory, "github-output"); + await writeFile(fixture, JSON.stringify({ artifacts, runs })); + await writeFile(output, ""); + await writeFile(calls, ""); + const fakeGh = join(fakeBin, "gh"); + await writeFile( + fakeGh, + [ + "#!/bin/sh", + 'printf \'%s\\n\' "$*" >> "$GH_API_CALLS"', + 'if [ "$GH_API_ERROR" = "true" ]; then exit 1; fi', + 'if [ "$4" = "repos/example/rea/actions/artifacts" ]; then', + ' node -e \'const fs=require("node:fs"); const x=JSON.parse(fs.readFileSync(process.env.GH_FIXTURE_RESPONSE,"utf8")); process.stdout.write(JSON.stringify({artifacts:x.artifacts}));\'', + "else", + ' run_id="${4##*/}"', + ' node -e \'const fs=require("node:fs"); const x=JSON.parse(fs.readFileSync(process.env.GH_FIXTURE_RESPONSE,"utf8")); process.stdout.write(JSON.stringify(x.runs[Number(process.argv[1])] ?? {}));\' "$run_id"', + "fi", + "", + ].join("\n"), + ); + await chmod(fakeGh, 0o755); + const node24 = dirname(process.execPath); + const result = await executeWorkflowFixture(process.execPath, [script], { + cwd: directory, + env: { + ...process.env, + PATH: [fakeBin, node24, process.env.PATH ?? ""].join(delimiter), + GH_FIXTURE_RESPONSE: fixture, + GH_API_CALLS: calls, + GH_API_ERROR: String(options.apiError ?? false), + GH_TOKEN: "fixture-token", + CI_REPOSITORY: options.repository ?? repository, + CI_REPOSITORY_ID: options.repositoryId ?? String(repositoryId), + CI_DEFAULT_BRANCH: "main", + GITHUB_OUTPUT: output, + }, + }); + return { + result, + output: await readFile(output, "utf8"), + calls: await readFile(calls, "utf8"), + }; +} + +it("selects the latest trusted full run that actually published timing history", async () => { + const { result, output, calls } = await invoke( + [ + artifact(15), + artifact(14), + artifact(13, { + workflow_run: { ...artifact(13).workflow_run, head_repository_id: 2 }, + }), + artifact(12, { + workflow_run: { ...artifact(12).workflow_run, head_branch: "feature" }, + }), + artifact(11), + ], + { + 15: run(15, { conclusion: "failure" }), + 14: run(14, { path: ".github/workflows/release.yml" }), + 11: run(11, { event: "workflow_dispatch" }), + }, + ); + + expect(JSON.parse(result.stdout)).toEqual({ run_id: "11" }); + expect(output).toBe("run-id=11\n"); + expect(calls).toContain("name=test-timings"); + expect(calls).toContain("per_page=100"); + expect(calls.match(/actions\/runs\//gu)).toHaveLength(3); + expect(calls).not.toContain("actions/workflows"); +}); + +it("rejects expired, foreign, old, and non-full run candidates", async () => { + const { result, output } = await invoke( + [ + artifact(15, { expired: true }), + artifact(14, { + workflow_run: { ...artifact(14).workflow_run, head_repository_id: 2 }, + }), + artifact(13, { + created_at: new Date(now - 31 * 24 * 60 * 60 * 1000).toISOString(), + }), + artifact(12), + ], + { + 12: run(12, { event: "pull_request" }), + }, + ); + + expect(JSON.parse(result.stdout)).toEqual({ run_id: "" }); + expect(output).toBe("run-id=\n"); +}); + +it("writes an empty run id when GitHub history is unavailable", async () => { + const { result, output } = await invoke([], {}, { apiError: true }); + expect(JSON.parse(result.stdout)).toEqual({ run_id: "" }); + expect(output).toBe("run-id=\n"); +}); + +it("bounds run lookups to five artifacts even when inventory has more", async () => { + const ids = [25, 24, 23, 22, 21, 20, 19]; + const { result, calls } = await invoke( + ids.map((id) => artifact(id)), + Object.fromEntries( + ids.map((id, index) => [ + id, + run(id, index < 5 ? { conclusion: "failure" } : {}), + ]), + ), + ); + + expect(JSON.parse(result.stdout)).toEqual({ run_id: "" }); + expect(calls.match(/actions\/runs\//gu)).toHaveLength(5); +}); + +it("returns empty history without querying for an invalid repository identity", async () => { + const { result, output, calls } = await invoke( + [], + {}, + { + repository: "owner/repo?per_page=100", + repositoryId: "not-an-id", + }, + ); + expect(JSON.parse(result.stdout)).toEqual({ run_id: "" }); + expect(output).toBe("run-id=\n"); + expect(calls).toBe(""); +}); diff --git a/tests/boundary/filesystem/ciTestReports.test.ts b/tests/boundary/filesystem/ciTestReports.test.ts index 0c9bb4ccf..06212ad07 100644 --- a/tests/boundary/filesystem/ciTestReports.test.ts +++ b/tests/boundary/filesystem/ciTestReports.test.ts @@ -1,5 +1,5 @@ import { execFile } from "node:child_process"; -import { readFile, writeFile } from "node:fs/promises"; +import { mkdir, readFile, rm, writeFile } from "node:fs/promises"; import { join, resolve } from "node:path"; import { fileURLToPath } from "node:url"; import { promisify } from "node:util"; @@ -8,8 +8,11 @@ import { expect, it } from "vitest"; import { parse } from "yaml"; import { z } from "zod"; +import { planTestSelection } from "../../../scripts/ci/test-selection.mjs"; + import { parseTestDurations } from "../../ciTestSequencer.js"; import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js"; +import { workflowGit } from "../../support/workflowGit.js"; const execute = promisify(execFile); const script = new URL("../../../scripts/ci/test-report.mjs", import.meta.url); @@ -53,6 +56,23 @@ it("collects failed-shard diagnostics before enforcing the shard result", async expect(upload).toBeGreaterThan(merge); expect(gate).toBeGreaterThan(upload); expect(steps[merge]?.if).not.toContain("needs.test-shard.result"); + const merges = steps.filter((step) => step.run?.includes("--reporter=json")); + expect(merges).toHaveLength(2); + for (const step of merges) + expect(step.run).toContain( + "--reporter=./scripts/ci/test-timing-reporter.mjs", + ); + expect(steps[upload]?.with?.path).toContain("test-timings.json"); + expect(steps[upload]?.with).toMatchObject({ "include-hidden-files": true }); + expect(steps[upload]?.with?.path).toContain( + ".cache/ci-test-selection/report.json", + ); + const summary = steps.find((step) => + step.run?.includes("scripts/ci/test-report.mjs"), + ); + expect(summary?.env?.CI_TEST_SELECTION).toBe( + "${{ needs.changes.outputs.test_selection }}", + ); const command = steps[gate]?.run; if (command === undefined) throw new Error("Missing shard result gate"); for (const result of ["failure", "cancelled", "skipped", ""]) { @@ -77,11 +97,67 @@ it("keeps diagnosis available after merge failure and publishes only complete su const history = steps.find((step) => step.with?.name === "test-timings"); expect(history?.if).toContain("success()"); expect(history?.if).toContain("needs.test-shard.result == 'success'"); + expect(history?.if).toContain("needs.changes.outputs.tier == 'full'"); expect(history?.with?.path).toBe(".cache/ci-test-history/test-results.json"); - const download = (await workflow()).build!.steps.find( + const buildSteps = (await workflow()).build!.steps; + const lookup = buildSteps.find((step) => + step.run?.includes("test-history.mjs"), + ); + expect(lookup?.env).toMatchObject({ + CI_REPOSITORY: "${{ github.repository }}", + CI_REPOSITORY_ID: "${{ github.repository_id }}", + CI_DEFAULT_BRANCH: "${{ github.event.repository.default_branch }}", + }); + const download = buildSteps.find( (step) => step.name === "Download previous timing report", ); expect(download?.with?.name).toBe(history?.with?.name); + expect(download?.with?.["run-id"]).toBe( + "${{ steps.history.outputs.run-id }}", + ); +}); + +it("rejects successful shard reports with missing or duplicate portable files", async () => { + const root = await createTestTempDirectory("rea-ci-report-inventory-"); + await workflowGit(root, ["init"]); + await mkdir(join(root, "tests")); + for (const name of ["first", "second"]) + await writeFile(join(root, `tests/${name}.test.ts`), "// fixture\n"); + await workflowGit(root, ["add", "tests"]); + const run = async (names: readonly string[]) => { + await writeFile( + join(root, "test-timings.json"), + JSON.stringify({ + version: 1, + success: true, + files: names.map((name) => ({ name, durationMs: 1 })), + }), + ); + return execute(process.execPath, [fileURLToPath(script)], { + cwd: root, + env: { + ...process.env, + SHARD_RESULT: "success", + MERGE_RESULT: "success", + CI_VERIFY_TEST_INVENTORY: "true", + }, + }); + }; + await expect( + run(["tests/first.test.ts", "tests/second.test.ts"]), + ).resolves.toMatchObject({ stderr: "" }); + for (const names of [ + ["tests/first.test.ts"], + ["tests/first.test.ts", "tests/second.test.ts", "tests/unplanned.test.ts"], + ["tests/first.test.ts", "tests/first.test.ts", "tests/second.test.ts"], + ]) { + await expect(run(names)).rejects.toMatchObject({ + stderr: expect.stringContaining("Incomplete portable test inventory"), + }); + await expect( + readFile(join(root, ".cache/ci-test-history/test-results.json")), + ).rejects.toMatchObject({ code: "ENOENT" }); + } }); it("runs the existing onboarding and Python producer guards from their selected CI owners", async () => { @@ -116,20 +192,25 @@ it("exports portable timing history and removes it on a failed, partial, or inva const summary = join(root, "summary.md"); const history = join(root, ".cache/ci-test-history/test-results.json"); const report = { + version: 1, success: true, - numFailedTests: 0, - testResults: [ + files: [ { name: join(root, "tests/slow.test.ts"), - startTime: 10, - endTime: 110, - assertionResults: [{ large: "not timing data" }], + durationMs: 100, + phases: { + execution: 20, + preparation: 20, + environment: 10, + imports: 40, + setup: 10, + }, }, - { name: join(root, "tests/fast.test.ts"), startTime: 20, endTime: 30 }, + { name: join(root, "tests/fast.test.ts"), durationMs: 10 }, ], }; const run = async (value: unknown, shards = "success", merge = "success") => { - await writeFile(join(root, "test-results.json"), JSON.stringify(value)); + await writeFile(join(root, "test-timings.json"), JSON.stringify(value)); await writeFile(summary, ""); return execute(process.execPath, [fileURLToPath(script)], { cwd: root, @@ -143,7 +224,8 @@ it("exports portable timing history and removes it on a failed, partial, or inva }; await run(report); const contents = await readFile(history, "utf8"); - expect(contents).not.toContain("assertionResults"); + expect(contents).not.toContain("phases"); + expect(contents).not.toContain("startTime"); expect(contents).not.toContain(root); expect( parseTestDurations(contents, resolve(root, "different-checkout")), @@ -154,7 +236,7 @@ it("exports portable timing history and removes it on a failed, partial, or inva ]), ); for (const [value, shards, merge] of [ - [{ ...report, success: false, numFailedTests: 1 }, "failure", "failure"], + [{ ...report, success: false }, "failure", "failure"], [report, "cancelled", "success"], [report, "success", "failure"], ] as const) { @@ -167,8 +249,211 @@ it("exports portable timing history and removes it on a failed, partial, or inva await expect( run({ ...report, - testResults: [{ name: "../outside.test.ts", startTime: 1, endTime: 3 }], + files: [{ name: "../outside.test.ts", durationMs: 2 }], + }), + ).rejects.toMatchObject({ code: 1 }); + await expect(readFile(history)).rejects.toMatchObject({ code: "ENOENT" }); + await run(report); + await expect( + run({ + ...report, + files: [{ name: "tests/invalid.test.ts", durationMs: -1 }], }), ).rejects.toMatchObject({ code: 1 }); await expect(readFile(history)).rejects.toMatchObject({ code: "ENOENT" }); }); + +it("recovers complete module costs from real blob reports without executing tests again", async () => { + const root = await createTestTempDirectory("rea-ci-module-timing-"); + const config = join(root, "vitest.config.mjs"); + await writeFile( + config, + 'export default { test: { globals: true, include: ["sample.test.js"], maxWorkers: 1 } };', + ); + await writeFile( + join(root, "sample.test.js"), + [ + 'import { writeFileSync } from "node:fs";', + "beforeAll(() => new Promise(resolve => setTimeout(resolve, 80)));", + "afterAll(() => new Promise(resolve => setTimeout(resolve, 80)));", + 'it("has cheap assertions and expensive outer hooks", () => { writeFileSync("executed", "yes"); expect(1).toBe(1); });', + ].join("\n"), + ); + const vitest = fileURLToPath( + new URL("../../../node_modules/vitest/vitest.mjs", import.meta.url), + ); + const reporter = fileURLToPath( + new URL("../../../scripts/ci/test-timing-reporter.mjs", import.meta.url), + ); + const run = (args: string[]) => + execute(process.execPath, [vitest, ...args, "--config", config], { + cwd: root, + env: process.env, + timeout: 20_000, + }); + await run(["run", "--reporter=blob"]); + expect(await readFile(join(root, "executed"), "utf8")).toBe("yes"); + await rm(join(root, "executed")); + await run([ + "--merge-reports", + `--reporter=${reporter}`, + "--reporter=json", + "--outputFile.json=body.json", + ]); + await expect(readFile(join(root, "executed"))).rejects.toMatchObject({ + code: "ENOENT", + }); + const report = z + .object({ + version: z.literal(1), + success: z.literal(true), + files: z.array( + z.object({ + name: z.string(), + durationMs: z.number(), + phases: z.record(z.string(), z.number()), + }), + ), + }) + .parse(JSON.parse(await readFile(join(root, "test-timings.json"), "utf8"))); + expect( + JSON.parse(await readFile(join(root, "test-timings.json"), "utf8")), + ).toMatchObject({ + reason: "passed", + unhandledErrors: 0, + files: [{ state: "passed" }], + }); + expect(report.files).toHaveLength(1); + const file = report.files[0]!; + const json = z + .object({ + testResults: z.array( + z.object({ startTime: z.number(), endTime: z.number() }), + ), + }) + .parse(JSON.parse(await readFile(join(root, "body.json"), "utf8"))); + const body = json.testResults[0]!; + expect( + file.phases.execution! - (body.endTime - body.startTime), + ).toBeGreaterThan(100); + expect(file.phases.imports).toBeGreaterThan(0); + expect(file.phases.preparation).toBeGreaterThan(0); + expect(file.durationMs).toBeCloseTo( + Object.values(file.phases).reduce((sum, value) => sum + value, 0), + ); + await execute(process.execPath, [fileURLToPath(script)], { + cwd: root, + env: { ...process.env, SHARD_RESULT: "success", MERGE_RESULT: "success" }, + }); + expect( + parseTestDurations( + await readFile( + join(root, ".cache/ci-test-history/test-results.json"), + "utf8", + ), + root, + )?.get("sample.test.js"), + ).toBe(file.durationMs); + + await writeFile( + join(root, "sample.test.js"), + 'it("fails", () => { throw new Error("fixture failure"); });', + ); + await expect(run(["run", "--reporter=blob"])).rejects.toMatchObject({ + code: 1, + }); + await expect( + run(["--merge-reports", `--reporter=${reporter}`]), + ).rejects.toMatchObject({ code: 1 }); + const failed = JSON.parse( + await readFile(join(root, "test-timings.json"), "utf8"), + ) as unknown; + expect(failed).toMatchObject({ + version: 1, + success: false, + reason: "failed", + unhandledErrors: 0, + files: [{ state: "failed" }], + }); + // Even a caller accidentally marking the merge successful cannot publish this report. + await execute(process.execPath, [fileURLToPath(script)], { + cwd: root, + env: { ...process.env, SHARD_RESULT: "success", MERGE_RESULT: "success" }, + }); + await expect( + readFile(join(root, ".cache/ci-test-history/test-results.json")), + ).rejects.toMatchObject({ code: "ENOENT" }); +}); + +it("records failed omissions from full reports without treating partial or unhandled outcomes as parity", async () => { + const root = await createTestTempDirectory("rea-ci-selection-report-"); + await workflowGit(root, ["init"]); + const paths = [ + "src/sqlite/provider.test.ts", + "src/evm/provider.test.ts", + "tests/boundary/mcp/workflow.test.ts", + ]; + for (const path of paths) { + await mkdir(join(root, path, ".."), { recursive: true }); + await writeFile(join(root, path), "// fixture\n"); + } + await workflowGit(root, ["add", "src", "tests"]); + const timing = { + version: 1, + success: false, + reason: "failed", + unhandledErrors: 0, + files: paths.map((name, index) => ({ + name, + durationMs: 10, + state: index === 1 ? "failed" : "passed", + })), + }; + const run = async (report: unknown) => { + await writeFile(join(root, "test-timings.json"), JSON.stringify(report)); + await execute(process.execPath, [fileURLToPath(script)], { + cwd: root, + env: { + ...process.env, + SHARD_RESULT: "failure", + MERGE_RESULT: "failure", + CI_VERIFY_TEST_INVENTORY: "true", + CI_TEST_SELECTION: JSON.stringify( + planTestSelection(["src/sqlite/Provider.ts"], "pull_request", "fast"), + ), + GITHUB_SHA: "merge-sha", + CI_PR_HEAD_SHA: "pr-head-sha", + }, + }); + return JSON.parse( + await readFile( + join(root, ".cache/ci-test-selection/report.json"), + "utf8", + ), + ) as unknown; + }; + expect(await run(timing)).toMatchObject({ + observational: true, + complete: true, + selected: [paths[0], paths[2]], + omitted: [paths[1]], + missedFailures: [paths[1]], + executionSha: "merge-sha", + prHeadSha: "pr-head-sha", + }); + for (const report of [ + { ...timing, files: timing.files.slice(0, 1) }, + { ...timing, unhandledErrors: 1 }, + { ...timing, reason: "interrupted" }, + ]) + expect(await run(report)).toMatchObject({ complete: false }); + await expect(run({ ...timing, files: "invalid" })).rejects.toMatchObject({ + code: 1, + }); + await expect( + readFile(join(root, ".cache/ci-test-selection/report.json")), + ).rejects.toMatchObject({ code: "ENOENT" }); + await expect( + readFile(join(root, ".cache/ci-test-history/test-results.json")), + ).rejects.toMatchObject({ code: "ENOENT" }); +}); diff --git a/tests/boundary/filesystem/ciTestSequencer.test.ts b/tests/boundary/filesystem/ciTestSequencer.test.ts index 6177d9481..fec32826d 100644 --- a/tests/boundary/filesystem/ciTestSequencer.test.ts +++ b/tests/boundary/filesystem/ciTestSequencer.test.ts @@ -17,24 +17,24 @@ describe("CI test history", () => { const root = resolve("/workspace/rea"); const durations = parseTestDurations( JSON.stringify({ + version: 1, success: true, - numFailedTests: 0, - testResults: [ + files: [ { name: join(root, "tests/slow.test.ts"), - startTime: 10, - endTime: 110, + durationMs: 100, }, { name: join(root, "tests/slow.test.ts"), - startTime: 20, - endTime: 80, + durationMs: 60, }, { name: resolve(root, "../outside.test.ts"), - startTime: 10, - endTime: 1000, + durationMs: 990, }, + { name: "tests/negative.test.ts", durationMs: -1 }, + { name: "tests/zero.test.ts", durationMs: 0 }, + { name: "tests/invalid.test.ts", durationMs: "100" }, null, ], }), @@ -43,7 +43,20 @@ describe("CI test history", () => { expect(durations).toEqual(new Map([["tests/slow.test.ts", 100]])); expect( - parseTestDurations('{"success": false, "numFailedTests": 1}', root), + parseTestDurations('{"version": 1, "success": false, "files": []}', root), + ).toBeUndefined(); + // Legacy test-body spans must not be mixed with complete module costs. + expect( + parseTestDurations( + JSON.stringify({ + success: true, + numFailedTests: 0, + testResults: [ + { name: "tests/legacy.test.ts", startTime: 0, endTime: 100 }, + ], + }), + root, + ), ).toBeUndefined(); expect(parseTestDurations("not json", root)).toBeUndefined(); expect(parseTestDurations("null", root)).toBeUndefined(); diff --git a/tests/boundary/filesystem/ciVerifiedPackage.test.ts b/tests/boundary/filesystem/ciVerifiedPackage.test.ts new file mode 100644 index 000000000..ff5045024 --- /dev/null +++ b/tests/boundary/filesystem/ciVerifiedPackage.test.ts @@ -0,0 +1,137 @@ +import { createHash } from "node:crypto"; +import { mkdir, readFile, writeFile } from "node:fs/promises"; +import { join } from "node:path"; +import { fileURLToPath } from "node:url"; + +import { expect, it } from "vitest"; + +import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js"; +import { + executeWorkflowFixture, + workflowGit, +} from "../../support/workflowGit.js"; + +const validator = fileURLToPath( + new URL("../../../scripts/ci/verified-package.mjs", import.meta.url), +); +type Fixture = Awaited>; +type FixtureOptions = { + override?: Record; + manifestContents?: string; + writeManifest?: boolean; +}; + +it("validates a tarball against the exact checkout and current workflow attempt", async () => { + const fixture = await createFixture(); + const result = await validate(fixture); + + expect(result.stdout.trim()).toBe( + join(fixture.artifactDirectory, "package.tgz"), + ); + expect(await readFile(fixture.output, "utf8")).toBe( + `tarball=${join(fixture.artifactDirectory, "package.tgz")}\n`, + ); +}); + +it("rejects a workflow SHA that differs from the checked out HEAD", async () => { + const fixture = await createFixture(); + + await expect(validate(fixture, "c".repeat(40))).rejects.toThrow(); +}); + +it.each([ + ["wrong checkout SHA", { sourceSha: "c".repeat(40) }], + ["wrong workflow run", { runId: 124 }], + ["future workflow attempt", { runAttempt: 3 }], + ["wrong verifier platform", { platform: "darwin" }], + ["wrong verifier architecture", { architecture: "arm64" }], + ["wrong package digest", { sha256: "c".repeat(64) }], +])("rejects %s", async (_label, override) => { + const fixture = await createFixture({ override }); + + await expect(validate(fixture)).rejects.toThrow(); +}); + +it("accepts an earlier successful attempt from the same workflow run", async () => { + const fixture = await createFixture({ override: { runAttempt: 1 } }); + + await expect(validate(fixture)).resolves.toMatchObject({ + stdout: expect.any(String), + }); +}); + +it.each([ + ["malformed manifest", "{"], + ["manifest with missing fields", JSON.stringify({ schemaVersion: 1 })], +])("rejects %s", async (_label, contents) => { + const fixture = await createFixture({ manifestContents: contents }); + + await expect(validate(fixture)).rejects.toThrow(); +}); + +it("rejects an absent manifest", async () => { + const fixture = await createFixture({ writeManifest: false }); + + await expect(validate(fixture)).rejects.toThrow(); +}); + +async function createFixture({ + override = {}, + manifestContents, + writeManifest = true, +}: FixtureOptions = {}) { + const directory = await createTestTempDirectory("rea-verified-package-"); + await workflowGit(directory, ["init", "--initial-branch=main"]); + await writeFile( + join(directory, "package.json"), + '{"name":"fixture","version":"1.2.3"}\n', + ); + await workflowGit(directory, ["add", "package.json"]); + await workflowGit(directory, [ + "commit", + "-m", + "test: verified package fixture", + ]); + const sourceSha = await workflowGit(directory, ["rev-parse", "HEAD"]); + const artifactDirectory = join(directory, "artifact"); + await mkdir(artifactDirectory); + const archive = "verified tarball fixture"; + await writeFile(join(artifactDirectory, "package.tgz"), archive); + const manifest = { + schemaVersion: 1, + sourceSha, + runId: 123, + runAttempt: 2, + platform: "linux", + architecture: "x64", + packageVersion: "1.2.3", + nodeVersion: process.version, + sha256: createHash("sha256").update(archive).digest("hex"), + ...override, + }; + if (writeManifest) + await writeFile( + join(artifactDirectory, "manifest.json"), + manifestContents ?? JSON.stringify(manifest), + ); + const output = join(directory, "github-output"); + await writeFile(output, ""); + return { directory, sourceSha, artifactDirectory, output }; +} + +function validate(fixture: Fixture, sourceSha = fixture.sourceSha) { + return executeWorkflowFixture( + process.execPath, + [validator, "validate", fixture.artifactDirectory], + { + cwd: fixture.directory, + env: { + ...process.env, + GITHUB_SHA: sourceSha, + GITHUB_RUN_ID: "123", + GITHUB_RUN_ATTEMPT: "2", + GITHUB_OUTPUT: fixture.output, + }, + }, + ); +} diff --git a/tests/boundary/filesystem/releaseCheckpoint.test.ts b/tests/boundary/filesystem/releaseCheckpoint.test.ts index e3d425810..d511a6a58 100644 --- a/tests/boundary/filesystem/releaseCheckpoint.test.ts +++ b/tests/boundary/filesystem/releaseCheckpoint.test.ts @@ -649,9 +649,8 @@ it.skipIf(process.platform === "win32").each([ const sourceSha = await candidate(f, valid ? "6.0.0" : "5.1.0"); const workflow = z .object({ - jobs: z.record( - z.string(), - z.object({ + jobs: z.object({ + [job]: z.object({ steps: z.array( z.object({ name: z.string().optional(), @@ -659,7 +658,7 @@ it.skipIf(process.platform === "win32").each([ }), ), }), - ), + }), }) .parse( parse( diff --git a/tests/boundary/filesystem/releaseWorkflow.test.ts b/tests/boundary/filesystem/releaseWorkflow.test.ts index 0bfebd1d2..4d3859433 100644 --- a/tests/boundary/filesystem/releaseWorkflow.test.ts +++ b/tests/boundary/filesystem/releaseWorkflow.test.ts @@ -34,6 +34,12 @@ async function readReleaseWorkflow() { "release-proposal": jobSchema, "release-please": jobSchema, "merged-release": jobSchema, + qualification: z.object({ + if: z.string(), + needs: z.array(z.string()), + uses: z.string(), + with: z.record(z.string(), z.string()), + }), publish: jobSchema, "publish-mcp": jobSchema, }), @@ -271,10 +277,19 @@ it("binds npm and MCP publication to the same immutable release SHA", async () = release_created: "${{ steps.release.outputs.release_created }}", sha: "${{ steps.release.outputs.sha }}", }); - expect(workflow.jobs.publish.if).toContain("inputs.phase == 'publish'"); - expect(workflow.jobs.publish.if).toContain( + expect(workflow.jobs.qualification.if).toContain("inputs.phase == 'publish'"); + expect(workflow.jobs.qualification.if).toContain( "needs.release-please.outputs.release_created", ); + expect(workflow.jobs.qualification.uses).toBe("./.github/workflows/ci.yml"); + expect(workflow.jobs.qualification.with).toEqual({ + source_sha: + "${{ needs.merged-release.outputs.sha || needs.release-please.outputs.sha }}", + }); + expect(workflow.jobs.publish.needs).toContain("qualification"); + expect(workflow.jobs.publish.if).toContain( + "needs.qualification.result == 'success'", + ); expect(workflow.jobs["publish-mcp"].if).toContain( "needs.publish.result == 'success'", ); @@ -309,7 +324,7 @@ it("binds npm and MCP publication to the same immutable release SHA", async () = )?.run; expect(publishCommand).toContain("scripts/release-npm-tag.mjs"); expect(publishCommand).toContain( - 'npm publish --access public --tag "${tag}"', + 'npm publish "${VERIFIED_PACKAGE_TARBALL}" --access public --tag "${tag}"', ); for (const [version, tag] of [ ["6.1.0", "latest"], @@ -644,7 +659,7 @@ it("routes website verification through the central PR policy", async () => { // Publishing is irreversible. Keep the release authority invariant as a static // boundary check; it is not proof that package installation or publishing works. -it("requires package verification before publishing and retains the registry canary", async () => { +it("requires qualified package validation before publishing and retains the registry canary", async () => { const workflow = z .object({ jobs: z.object({ @@ -663,7 +678,7 @@ it("requires package verification before publishing and retains the registry can ); const commands = workflow.jobs.publish.steps.map(({ run }) => run ?? ""); const verify = commands.findIndex((command) => - command.includes("npm run verify:package"), + command.includes("scripts/ci/verified-package.mjs validate"), ); const publish = commands.findIndex((command) => command.includes("npm publish"), diff --git a/tests/boundary/filesystem/safeOutputTree.test.ts b/tests/boundary/filesystem/safeOutputTree.test.ts index f67704456..3e82a62ab 100644 --- a/tests/boundary/filesystem/safeOutputTree.test.ts +++ b/tests/boundary/filesystem/safeOutputTree.test.ts @@ -489,4 +489,28 @@ describe("safe artifact output Windows stream paths", () => { await expect(access(output)).rejects.toMatchObject({ code: "ENOENT" }); expect(await readdir(parent)).toEqual([]); }); + + it.each(["Folder/Icon\r", "Fold\ter/file.txt"])( + "refuses Windows control characters before creating %j", + async (path) => { + const parent = await createTestTempDirectory("rea-safe-output-control-"); + const output = join(parent, "published"); + const tree = await SafeOutputTree.create(output, "win32"); + const bytes = Buffer.from("regular file content"); + await expect( + tree.write(path, Readable.from(bytes), { + sha256: createHash("sha256").update(bytes).digest("hex"), + bytes: bytes.byteLength, + }), + ).rejects.toMatchObject({ + reason: "path", + message: `Windows destination cannot materialize artifact path: ${JSON.stringify(path)}; Windows names cannot contain U+0001-U+001F.`, + }); + expect(await readdir(output)).toEqual([]); + expect(await tree.rollback()).toEqual({ + status: "complete", + residualPaths: [], + }); + }, + ); }); diff --git a/tests/boundary/filesystem/testTaskCache.test.ts b/tests/boundary/filesystem/testTaskCache.test.ts index 7e06ce1a1..5d877e829 100644 --- a/tests/boundary/filesystem/testTaskCache.test.ts +++ b/tests/boundary/filesystem/testTaskCache.test.ts @@ -1,6 +1,6 @@ import { execFile } from "node:child_process"; -import { readFile, writeFile } from "node:fs/promises"; -import { join } from "node:path"; +import { cp, readFile, writeFile } from "node:fs/promises"; +import { basename, join } from "node:path"; import { promisify } from "node:util"; import { expect, it } from "vitest"; @@ -78,7 +78,7 @@ it.skipIf(process.platform === "android")( await workflowGit(root, ["init", "--initial-branch=main"]); await workflowGit(root, ["add", "."]); await workflowGit(root, ["commit", "-m", "test: seed cache fixture"]); - const run = () => + const run = (cwd = root) => execute( process.execPath, [ @@ -87,7 +87,7 @@ it.skipIf(process.platform === "android")( "test:run", "--output-logs=errors-only", ], - { cwd: root, env: { ...process.env, TURBO_DAEMON: "false" } }, + { cwd, env: { ...process.env, TURBO_DAEMON: "false" } }, ); await run(); await writeFile(join(root, "README_zh.md"), "wrong command"); @@ -104,5 +104,32 @@ it.skipIf(process.platform === "android")( "prepared\n", ); } + // Provider jobs receive the producer's cache in a fresh checkout, not its + // outputs. Turbo must restore identical inputs and rebuild changed ones. + const consumer = await createTestTempDirectory("rea-cache-consumer-"); + await cp(root, consumer, { + recursive: true, + filter: (path) => + basename(path) !== ".turbo" && + !/^prepared-\d+\.txt$/u.test(basename(path)), + }); + await cp(join(root, ".turbo/cache"), join(consumer, ".turbo/cache"), { + recursive: true, + }); + const restored = await run(consumer); + expect(restored.stdout).toContain(`${dependencies.length} cached`); + for (const index of dependencies.keys()) + expect( + await readFile(join(consumer, `prepared-${index}.txt`), "utf8"), + ).toBe("prepared\n"); + await writeFile( + join(consumer, "artifact-input.txt"), + "changed producer input", + ); + await run(consumer); + for (const index of dependencies.keys()) + expect( + await readFile(join(consumer, `prepared-${index}.txt`), "utf8"), + ).toBe("prepared\nprepared\n"); }, ); diff --git a/tests/boundary/mcp/enhancedTools.04-uses-complete-inventories-inline.test.ts b/tests/boundary/mcp/enhancedTools.04-uses-complete-inventories-inline.test.ts index 8e3a39969..e452d70c3 100644 --- a/tests/boundary/mcp/enhancedTools.04-uses-complete-inventories-inline.test.ts +++ b/tests/boundary/mcp/enhancedTools.04-uses-complete-inventories-inline.test.ts @@ -144,14 +144,26 @@ describe("enhanced MCP tools", () => { ); expect(result).toEqual({ document: "fixture", + image_base: "0x1000", segments: [ - { name: "__TEXT", start: "0x1000", end: "0x1800", length: 2048 }, - { name: "__DATA", start: "0x1800", end: "0x2000", length: 2048 }, + { + name: "__TEXT", + start: "0x1000", + end: "0x1800", + length: 2048, + image_base: "0x1000", + }, + { + name: "__DATA", + start: "0x1800", + end: "0x2000", + length: 2048, + image_base: "0x1000", + }, ], segment_count: 2, procedure_count: 2, string_count: 700, - image_base: "0x1000", }); }); diff --git a/tests/boundary/mcp/nativeAddressContextMcp.test.ts b/tests/boundary/mcp/nativeAddressContextMcp.test.ts new file mode 100644 index 000000000..5b855fc26 --- /dev/null +++ b/tests/boundary/mcp/nativeAddressContextMcp.test.ts @@ -0,0 +1,121 @@ +import { afterEach, expect, it } from "vitest"; +import { Ajv2020 } from "ajv/dist/2020.js"; +import type { AnySchemaObject } from "ajv"; +import { + closeEnhancedToolResources, + connect, + jsonResult, +} from "./enhancedToolsHarness.js"; +import { observed as ok } from "../../fixtures/analysisExecution.js"; +import type { SegmentSummary } from "../../../src/domain/hopperValues.js"; + +afterEach(closeEnhancedToolResources); + +const segment = { + name: ".text", + start: "0x101000", + end: "0x101100", + readable: true, + writable: false, + executable: true, + image_base: "0x100000", + address_space: "ram", +}; +const overviewClient = (segments: SegmentSummary[]) => + connect({ + execute: (name) => { + switch (name) { + case "current_document": + return Promise.resolve(ok("fixture")); + case "list_documents": + return Promise.resolve(ok(["fixture"])); + case "list_segments": + return Promise.resolve(ok(segments)); + case "list_procedures": + return Promise.resolve(ok([{ address: "0x101013", value: "entry" }])); + case "list_strings": + return Promise.resolve(ok([])); + default: + throw new Error(`Unexpected operation: ${name}`); + } + }, + }); + +it("preserves observed coordinates and main's optional-string output contract after SDK conversion", async () => { + const client = await overviewClient([segment]); + const schema = (await client.listTools()).tools.find( + ({ name }) => name === "binary_overview", + )?.outputSchema; + if (schema === undefined) throw new Error("Missing overview output schema"); + const validate = new Ajv2020({ strict: false }).compile( + schema as AnySchemaObject, + ); + const response = await client.callTool({ + name: "binary_overview", + arguments: {}, + }); + expect(validate(response.structuredContent)).toBe(true); + expect(jsonResult(response)).toMatchObject({ + image_base: "0x100000", + segments: [ + { start: "0x101000", image_base: "0x100000", address_space: "ram" }, + ], + }); + const absent = JSON.parse(JSON.stringify(response.structuredContent)); + delete absent.normalized_result.image_base; + expect(validate(absent)).toBe(true); + absent.normalized_result.image_base = null; + expect(validate(absent)).toBe(false); +}); + +it("omits unreported bases without inventing zero and preserves explicit zero", async () => { + const { image_base: _base, ...unreported } = segment; + const client = await overviewClient([unreported]); + expect( + jsonResult( + await client.callTool({ name: "binary_overview", arguments: {} }), + ), + ).not.toHaveProperty("image_base"); + const zero = await overviewClient([{ ...segment, image_base: "0x0" }]); + expect( + jsonResult(await zero.callTool({ name: "binary_overview", arguments: {} })), + ).toMatchObject({ image_base: "0x0" }); +}); + +it("keeps a partially reported base unknown while retaining the reported segment observation", async () => { + const { image_base: _base, ...unreported } = segment; + const client = await overviewClient([ + segment, + { ...unreported, name: ".data" }, + ]); + const result = jsonResult( + await client.callTool({ name: "binary_overview", arguments: {} }), + ); + expect(result).not.toHaveProperty("image_base"); + expect(result).toMatchObject({ + segments: [{ image_base: "0x100000" }, { name: ".data" }], + }); +}); + +it("retains all conflicting observations after repeated early bases without selecting one", async () => { + const { address_space: _space, ...unreported } = segment; + const client = await overviewClient([ + ...Array.from({ length: 40 }, () => unreported), + { + ...segment, + name: ".data", + start: "other%20space:0x201000", + end: "other%20space:0x201100", + image_base: "0x200000", + address_space: "other space", + }, + ]); + const result = jsonResult( + await client.callTool({ name: "binary_overview", arguments: {} }), + ); + expect(result).not.toHaveProperty("image_base"); + expect(result).toHaveProperty("segments.length", 41); + expect(result).toHaveProperty("segments.40.image_base", "0x200000"); + expect(result).toHaveProperty("segments.40.address_space", "other space"); + expect(result).not.toHaveProperty("segments.0.address_space"); +}); diff --git a/tests/boundary/providers/managed/managedMemberComparisonFromMetadata.test.ts b/tests/boundary/providers/managed/managedMemberComparisonFromMetadata.test.ts index 7f4408811..56014fbd4 100644 --- a/tests/boundary/providers/managed/managedMemberComparisonFromMetadata.test.ts +++ b/tests/boundary/providers/managed/managedMemberComparisonFromMetadata.test.ts @@ -116,6 +116,66 @@ describe("managed member comparison", () => { }); }); +describe("managed member comparison floating-point constants", () => { + it.each([ + { + opcode: "ldc.r4", + positive: "22000000002a", + negative: "22000000802a", + type: 0x0c, + }, + { + opcode: "ldc.r8", + positive: "2300000000000000002a", + negative: "2300000000000000802a", + type: 0x0d, + }, + ])( + "detects a change from positive to negative zero in $opcode", + ({ opcode, positive, negative, type }) => { + const observe = (hex: string, path: string) => { + const il = Buffer.from(hex, "hex"); + return inspect( + buildManagedPeFixture({ + methodSignature: Buffer.from([0x00, 0x00, type]), + ilBody: Buffer.concat([Buffer.from([(il.length << 2) | 2]), il]), + }), + path, + ); + }; + const left = observe(positive, "/tmp/positive-zero.dll"); + const right = observe(negative, "/tmp/negative-zero.dll"); + const comparison = compareManagedMembers(left, right); + + expect(comparison.methods[0]).toMatchObject({ + status: "changed", + match: { status: "matched", basis: "exact-signature" }, + dimensions: ["cil"], + }); + for (const [observation, operand] of [ + [left, "0"], + [right, "-0"], + ] as const) { + expect(observation.result.methods[0]?.body).toMatchObject({ + status: "present", + anchors: [ + { il_offset: 0, opcode, operand_kind: "constant", operand }, + ], + }); + } + expect(left.result.methods[0]?.body.normalized_il_sha256).not.toBe( + right.result.methods[0]?.body.normalized_il_sha256, + ); + const repeated = observe(negative, "/tmp/negative-zero-copy.dll"); + expect(compareManagedMembers(right, repeated).methods[0]).toMatchObject({ + status: "unchanged", + match: { status: "matched", basis: "exact-il-signature" }, + dimensions: [], + }); + }, + ); +}); + describe("managed member comparison uncertainty", () => { it("does not infer a structural method match from undecoded signature fields", () => { const left = inspect( diff --git a/tests/boundary/providers/native/nativeProvider.test.ts b/tests/boundary/providers/native/nativeProvider.test.ts index 3dd2a9b2c..0d1860b16 100644 --- a/tests/boundary/providers/native/nativeProvider.test.ts +++ b/tests/boundary/providers/native/nativeProvider.test.ts @@ -61,7 +61,13 @@ afterEach(async () => { }); describe("native macOS provider discovery", () => { - it.each(["ordinary.fixture", " spaced.fixture ", " leading", "trailing "])( + it.each([ + "ordinary.fixture", + " spaced.fixture ", + " leading", + "trailing ", + "literal\r\nidentifier\r", + ])( "preserves the exact signing identifier %j reported by codesign", (identifier) => { const parsed = parseCodeSignature( @@ -74,31 +80,68 @@ describe("native macOS provider discovery", () => { }, ); - it("separates echoed path and identifier text from signature fields", () => { - const path = "/apps/x\nAuthority=Forged\nIdentifier=forged"; - const identifier = "x\nFormat=forged\nAuthority=Forged-5555"; - const parsed = parseCodeSignature( - [ - `Executable=${path}`, - `Identifier=${identifier}`, - "Format=Mach-O thin (arm64)", - "CodeDirectory v=20400 size=342 flags=0x2(adhoc) hashes=2+2", - "CDHash=6aee90e6", - "Signature=adhoc", - "TeamIdentifier=not set", - "", - ].join("\r\n"), - false, - ["/elsewhere", path], - ); - expect(parsed).toMatchObject({ - identifier, - format: "Mach-O thin (arm64)", - authorities: [], - cdhashes: ["6aee90e6"], - team_identifier: null, - }); - }); + it.each(["\n", "\r\n"])( + "separates echoed path and identifier text from signature fields (%j)", + (newline) => { + const path = "/apps/x\r\nAuthority=Forged\nIdentifier=forged"; + const identifier = "x\r\nFormat=forged\nAuthority=Forged-5555\r"; + const parsed = parseCodeSignature( + [ + `Executable=${path}`, + `Identifier=${identifier}`, + "Format=Mach-O thin (arm64)", + "CodeDirectory v=20400 size=342 flags=0x2(adhoc) hashes=2+2", + "CDHash=6aee90e6", + "Signature=adhoc", + "TeamIdentifier=not set", + "", + ].join(newline), + false, + ["/elsewhere", path], + ); + expect(parsed).toMatchObject({ + identifier, + format: "Mach-O thin (arm64)", + authorities: [], + cdhashes: ["6aee90e6"], + team_identifier: null, + }); + }, + ); + + it.each([ + { executable: "", paths: [], newline: "\r\n", identifier: "fixture" }, + { + executable: "Executable=/apps/fixture\r\n", + paths: [], + newline: "\r\n", + identifier: "fixture\nFormat=payload\r", + }, + { + executable: "Executable=/apps/fixture\n", + paths: ["/elsewhere"], + newline: "\n", + identifier: "fixture\r\nFormat=payload\r", + }, + { + executable: "Executable=/apps/fixture\r\n", + paths: ["/elsewhere"], + newline: "\r\n", + identifier: "fixture\r", + }, + ])( + "frames the identifier without a matching executable path: %j", + ({ executable, paths, newline, identifier }) => { + const parsed = parseCodeSignature( + `${executable}Identifier=${identifier}${newline}Format=Mach-O thin (arm64)${newline}TeamIdentifier=not set${newline}`, + false, + paths, + ); + expect(parsed.identifier).toBe(identifier); + expect(parsed.format).toBe("Mach-O thin (arm64)"); + expect(parsed.team_identifier).toBeNull(); + }, + ); it.each(["timeout", "output-limit"] as const)( "preserves %s resolution failures with their captured output and cleanup status", diff --git a/tests/boundary/providers/native/nativeSelectedArchitecture.test.ts b/tests/boundary/providers/native/nativeSelectedArchitecture.test.ts index 006b13003..a651e22f6 100644 --- a/tests/boundary/providers/native/nativeSelectedArchitecture.test.ts +++ b/tests/boundary/providers/native/nativeSelectedArchitecture.test.ts @@ -1,7 +1,11 @@ import { expect, it } from "vitest"; +import { CPU } from "../../../../src/artifacts/apple/MachoImage.fixture.js"; import { inspectMachoSchema } from "../../../../src/domain/native/nativeInspection.js"; import { err } from "../../../../src/domain/result.js"; -import { NativeCommandFailure } from "../../../../src/native/CommandRunner.js"; +import { + NativeCommandFailure, + type NativeCommandRunner, +} from "../../../../src/native/CommandRunner.js"; import { NativeMacOSProvider } from "../../../../src/native/NativeMacOSProvider.js"; import { NativeFixtureRunner, @@ -9,6 +13,35 @@ import { nativeMachoTarget, } from "../../../fixtures/nativeCommands.js"; +/** Replay fixtures, failing any slice command that does not name the expected slice. */ +const sliceSelectingRunner = ( + fixtures: NativeFixtureRunner, + selected: string, + dyldArchitecture: string, + calls: { + readonly tool: string; + readonly arguments_: readonly string[]; + }[] = [], +): NativeCommandRunner => ({ + run(tool, arguments_) { + calls.push({ tool, arguments_ }); + const expected = tool === "dyld_info" ? dyldArchitecture : selected; + if ( + !["file", "lipo"].includes(tool) && + !arguments_.some( + (argument, index) => + argument === expected || + argument === `--arch=${expected}` || + (argument === "-arch" && arguments_[index + 1] === expected), + ) + ) + return Promise.resolve( + err(new NativeCommandFailure(tool, "nonzero-exit", 1)), + ); + return fixtures.run(tool, arguments_); + }, +}); + it("does not attribute the first universal slice's UUID and segments to the selected target", async () => { const singleSlice = await nativeFixture("otool-load.txt"); const selected = new NativeFixtureRunner(); @@ -58,18 +91,39 @@ it.each([ selected: "arm64e", dyldArchitecture: "arm64e.v1", }, -])( + { + architectures: ["arm64v8", "arm64e.v1"], + selected: "arm64e", + dyldArchitecture: "arm64e.v1", + }, + { + architectures: ["arm64e.v1", "arm64v8"], + selected: "arm64e", + dyldArchitecture: "arm64e.v1", + }, +] as const)( "selects the $dyldArchitecture slice of a universal arm64e target", async ({ architectures, selected, dyldArchitecture }) => { const calls: { readonly tool: string; readonly arguments_: readonly string[]; }[] = []; + const cpus = { + x86_64: CPU.x86_64, + arm64e: CPU.arm64e, + arm64v8: { type: CPU.arm64.type, subtype: 1 }, + "arm64e.x1": { type: CPU.arm64.type, subtype: 0x8000000c }, + "arm64e.v1": { type: CPU.arm64.type, subtype: 0x81000002 }, + }; const lipo = architectures - .map( - (architecture, index) => - `architecture ${architecture}\n cputype 16777228\n cpusubtype 2\n offset ${index * 16384}\n size 8192\n align 2^14 (16384)`, - ) + .map((architecture, index) => { + const cpu = cpus[architecture]; + const subtype = + architecture === "arm64e.v1" + ? "CPU_SUBTYPE_ARM64E\n capabilities PTR_AUTH_VERSION USERSPACE 1" + : String(cpu.subtype); + return `architecture ${architecture}\n cputype ${cpu.type}\n cpusubtype ${subtype}\n offset ${index * 16384}\n size 8192\n align 2^14 (16384)`; + }) .join("\n"); const fixtures = new NativeFixtureRunner({ lipo, @@ -77,25 +131,7 @@ it.each([ }); const client = new NativeMacOSProvider( {}, - { - run(tool, arguments_) { - calls.push({ tool, arguments_ }); - const expected = tool === "dyld_info" ? dyldArchitecture : selected; - if ( - !["file", "lipo"].includes(tool) && - !arguments_.some( - (argument, index) => - argument === expected || - argument === `--arch=${expected}` || - (argument === "-arch" && arguments_[index + 1] === expected), - ) - ) - return Promise.resolve( - err(new NativeCommandFailure(tool, "nonzero-exit", 1)), - ); - return fixtures.run(tool, arguments_); - }, - }, + sliceSelectingRunner(fixtures, selected, dyldArchitecture, calls), "darwin", ).createClient(nativeMachoTarget("/owned/universal")); @@ -104,6 +140,11 @@ it.each([ if (!result.ok) throw result.error; expect(result.value.result).toMatchObject({ uuid: "01234567-89AB-CDEF-0123-456789ABCDEF", + selected_architecture: { + name: dyldArchitecture, + container_file_offset: + architectures.findIndex((name) => name === dyldArchitecture) * 16384, + }, architectures: { items: architectures.map((name) => ({ name })), }, @@ -116,6 +157,36 @@ it.each([ }, ); +it.each([ + { capture: "calculator.txt", selected: "arm64e" }, + { capture: "shortcut-droplet.txt", selected: "arm64" }, +])( + "selects one slice when every universal slice has the target's CPU type ($capture)", + async ({ capture, selected }) => { + const base = nativeMachoTarget("/owned/universal"); + if (base.kind !== "executable") + throw new Error("Expected executable fixture"); + // Admission names arm64, arm64e and arm64e.x1 slices by one CPU family. + const target = { ...base, availableArchitectures: ["arm64"] as const }; + const fixtures = new NativeFixtureRunner({ + lipo: await nativeFixture(`lipo-same-cpu/${capture}`), + }); + const result = await new NativeMacOSProvider( + {}, + sliceSelectingRunner(fixtures, selected, selected), + "darwin", + ) + .createClient(target) + .execute("inspect_macho", {}); + + if (!result.ok) throw result.error; + expect(result.value.result).toMatchObject({ + selected_architecture: { name: selected, container_file_offset: 16384 }, + architectures: { total: 2 }, + }); + }, +); + it("projects universal segment evidence into the selected slice's container offsets", async () => { const client = new NativeMacOSProvider( {}, diff --git a/tests/ciTestSequencer.ts b/tests/ciTestSequencer.ts index 5e8c4fe5f..996e8ce7a 100644 --- a/tests/ciTestSequencer.ts +++ b/tests/ciTestSequencer.ts @@ -5,14 +5,13 @@ import { BaseSequencer, type TestSpecification } from "vitest/node"; import { z } from "zod"; const reportSchema = z.object({ + version: z.literal(1), success: z.literal(true), - numFailedTests: z.literal(0), - testResults: z.array(z.unknown()), + files: z.array(z.unknown()), }); const fileSchema = z.object({ name: z.string(), - startTime: z.number(), - endTime: z.number(), + durationMs: z.number().finite().positive(), }); export function parseTestDurations( @@ -30,15 +29,12 @@ export function parseTestDurations( if (!report.success) return undefined; const durations = new Map(); - for (const value of report.data.testResults) { + for (const value of report.data.files) { const result = fileSchema.safeParse(value); if (!result.success) continue; - const { name, startTime, endTime } = result.data; - const duration = endTime - startTime; + const { name, durationMs } = result.data; const path = relative(root, resolve(root, name)); if ( - !Number.isFinite(duration) || - duration <= 0 || path === "" || path === ".." || path.startsWith(".." + sep) || @@ -46,7 +42,7 @@ export function parseTestDurations( ) continue; const key = path.split(sep).join("/"); - durations.set(key, Math.max(durations.get(key) ?? 0, duration)); + durations.set(key, Math.max(durations.get(key) ?? 0, durationMs)); } return durations.size ? durations : undefined; } diff --git a/tests/conformance/c/pie-address-context.c b/tests/conformance/c/pie-address-context.c new file mode 100644 index 000000000..970d2fc6e --- /dev/null +++ b/tests/conformance/c/pie-address-context.c @@ -0,0 +1,7 @@ +__attribute__((noinline)) int rea_pie_add(int value) { + return value + 7; +} + +int rea_pie_entry(void) { + return rea_pie_add(35); +} diff --git a/tests/conformance/ghidra/ReaFileOffsetSourceProbe.java b/tests/conformance/ghidra/ReaFileOffsetSourceProbe.java new file mode 100644 index 000000000..57da9d28e --- /dev/null +++ b/tests/conformance/ghidra/ReaFileOffsetSourceProbe.java @@ -0,0 +1,118 @@ +//@category REA Verification + +import java.io.ByteArrayInputStream; +import java.io.PrintWriter; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Locale; + +import com.google.gson.JsonNull; +import com.google.gson.JsonObject; +import ghidra.app.script.GhidraScriptUtil; +import ghidra.app.util.headless.HeadlessScript; +import ghidra.program.model.address.AddressSet; +import ghidra.program.model.listing.Function; +import ghidra.program.model.symbol.SourceType; +import ghidra.app.decompiler.DecompInterface; +import ghidra.app.decompiler.DecompileResults; +import ghidra.app.decompiler.DecompileProcess.DisposeState; +import ghidra.util.task.TaskMonitor; + +/** Real source-identity cases unavailable through ordinary single-file CLI imports. */ +public final class ReaFileOffsetSourceProbe extends HeadlessScript { + @Override + public void run() throws Exception { + var file = GhidraScriptUtil.findScriptByName("ReaGhidraBridge.java"); + var bridge = GhidraScriptUtil.getProvider(file).getScriptInstance(file, new PrintWriter(System.out, true)); + bridge.set(state, monitor, new PrintWriter(System.out, true)); + var space = bridge.getClass().getDeclaredField("sessionDefaultAddressSpace"); + space.setAccessible(true); + space.set(null, currentProgram.getAddressFactory().getDefaultAddressSpace()); + var identity = bridge.getClass().getDeclaredField("admittedTargetSha256"); + identity.setAccessible(true); + identity.set(bridge, currentProgram.getExecutableSHA256().toLowerCase(Locale.ROOT)); + var resolve = bridge.getClass().getDeclaredMethod("resolveDecompileProcedure", String.class, JsonObject.class); + resolve.setAccessible(true); + var reverse = bridge.getClass().getDeclaredMethod("addressToFileOffset", JsonObject.class); + reverse.setAccessible(true); + + var memory = currentProgram.getMemory(); + var original = memory.getAllFileBytes().get(0); + byte[] bytes = new byte[Math.toIntExact(original.getSize())]; + require(original.getOriginalBytes(0, bytes) == bytes.length, "complete fixture source"); + byte[] auxiliary = new byte[0x1000]; + auxiliary[0x910] = (byte)0xc3; + var foreign = memory.createFileBytes("auxiliary.bin", 0, auxiliary.length, + new ByteArrayInputStream(auxiliary), monitor); + var address = toAddr(0x140100000L); + memory.createInitializedBlock("auxiliary", address, foreign, 0, auxiliary.length, false); + var entry = address.add(0x910); + currentProgram.getFunctionManager().createFunction("foreign_only", entry, + new AddressSet(entry), SourceType.USER_DEFINED); + rejected(resolve, bridge, "no loaded source mapping", "file-offset:0x910", new JsonObject()); + rejected(reverse, bridge, "0 authoritative target-file mappings", reverseInput("0x140100910")); + + // A source object's declared original-file start does not make its local + // offsets a complete, digest-matched target representation. + var partial = memory.createFileBytes("partial.bin", 0x200, 0x200, + new ByteArrayInputStream(bytes, 0x200, 0x200), monitor); + memory.createInitializedBlock("partial", toAddr(0x140300000L), partial, 0, 0x200, false); + rejected(reverse, bridge, "0 authoritative target-file mappings", reverseInput("0x140300010")); + var selected = (Function)resolve.invoke(bridge, "file-offset:0x210", new JsonObject()); + require(selected.getEntryPoint().equals(toAddr(0x140001010L)), "original target selected despite other sources"); + var mapped = (JsonObject)reverse.invoke(bridge, reverseInput("0x140001010")); + require(mapped.get("file_offset").getAsLong() == 0x210, "original target round trip"); + + // Inject backend failures after real source/function resolution. This + // verifies context propagation, not a naturally failing decompiler. + var pseudocode = bridge.getClass().getDeclaredMethod("procedurePseudocode", JsonObject.class); + pseudocode.setAccessible(true); + var decompiler = bridge.getClass().getDeclaredField("decompiler"); + decompiler.setAccessible(true); + JsonObject request = new JsonObject(); + request.add("document", JsonNull.INSTANCE); + request.addProperty("procedure", "file-offset:0x210"); + for (DisposeState disposition : new DisposeState[] { DisposeState.NOT_DISPOSED, DisposeState.DISPOSED_ON_CANCEL }) { + decompiler.set(bridge, new DecompInterface() { + @Override + public DecompileResults decompileFunction(Function function, int timeout, TaskMonitor taskMonitor) { + return new DecompileResults(function, currentProgram.getLanguage(), + currentProgram.getCompilerSpec(), null, "Injected backend failure", null, disposition); + } + }); + Throwable failure = rejected(pseudocode, bridge, + "Selector file-offset:0x210 mapped to analysis address 0x140001010 and procedure 0x140001010", request); + var code = failure.getClass().getDeclaredField("code"); + code.setAccessible(true); + require(code.get(failure).equals(disposition == DisposeState.DISPOSED_ON_CANCEL + ? "decompile_cancelled" : "decompile_failed"), "backend failure code retained"); + } + + var duplicate = memory.createFileBytes("duplicate.bin", 0, bytes.length, + new ByteArrayInputStream(bytes), monitor); + memory.createInitializedBlock("duplicate", toAddr(0x140201000L), duplicate, 0x200, 0x200, false); + rejected(resolve, bridge, "multiple loaded mappings", "file-offset:0x210", new JsonObject()); + println("REA_FILE_OFFSET_SOURCE_OK foreign/partial rejected; original round trip; duplicate ambiguity; injected backend failure context retained"); + } + + private JsonObject reverseInput(String address) { + JsonObject params = new JsonObject(); + params.add("document", JsonNull.INSTANCE); + params.addProperty("address", address); + return params; + } + + private Throwable rejected(Method method, Object bridge, String reason, Object... arguments) throws Exception { + try { + method.invoke(bridge, arguments); + } catch (InvocationTargetException rejected) { + require(rejected.getCause().getMessage().contains(reason), "expected mapping failure: " + reason); + return rejected.getCause(); + } + throw new AssertionError("Expected mapping failure: " + reason); + } + + private void require(boolean condition, String message) { + if (!condition) throw new AssertionError(message); + } +} diff --git a/tests/evaluation/ciTestSelection.test.ts b/tests/evaluation/ciTestSelection.test.ts new file mode 100644 index 000000000..1dff7f9e3 --- /dev/null +++ b/tests/evaluation/ciTestSelection.test.ts @@ -0,0 +1,240 @@ +import { expect, it } from "vitest"; + +import { + compareTestSelection, + planTestSelection, +} from "../../scripts/ci/test-selection.mjs"; + +const sqliteSource = "src/sqlite/SqliteDatabaseProvider.test.ts"; +const sqliteBoundary = "tests/boundary/sqlite/sqliteDatabaseProvider.test.ts"; +const adbSource = "src/adb/AdbProvider.test.ts"; +const adbBoundary = + "tests/boundary/providers/adb/adbBugreportPublication.test.ts"; +const cliBoundary = "tests/boundary/cli/apktoolCli.test.ts"; +const mcpBoundary = "tests/boundary/mcp/apktoolMcp.test.ts"; +const processBoundary = + "tests/boundary/process/processCaptureLifecycle.test.ts"; +const acceptance = "tests/acceptance/tools/localToolContracts.test.ts"; +const composition = "tests/composition/directAnalysisCleanup.test.ts"; +const evaluation = "tests/evaluation/testDiscovery.test.ts"; + +const passed = (name: string) => ({ name, durationMs: 10, state: "passed" }); + +it("unions affected leaf owners, keeps changed tests and retains unowned integration tests", () => { + const plan = planTestSelection( + ["src/sqlite/SqliteDatabaseProvider.ts", adbBoundary], + "pull_request", + "fast", + ); + const inventory = [ + sqliteSource, + sqliteBoundary, + adbSource, + adbBoundary, + cliBoundary, + mcpBoundary, + processBoundary, + acceptance, + composition, + evaluation, + ]; + const report = compareTestSelection(plan, inventory, inventory.map(passed)); + + expect(plan).toMatchObject({ + mode: "candidate", + owners: ["adb", "sqlite"], + }); + expect(report.selected).toEqual( + expect.arrayContaining([ + sqliteSource, + sqliteBoundary, + adbSource, + adbBoundary, + cliBoundary, + mcpBoundary, + processBoundary, + acceptance, + composition, + evaluation, + ]), + ); + expect(report.omitted).toEqual([]); +}); + +it("omits only unrelated owned tests while retaining dynamic boundary suites", () => { + const plan = planTestSelection( + ["src/sqlite/SqliteDatabaseProvider.ts"], + "pull_request", + "fast", + ); + const inventory = [ + sqliteSource, + sqliteBoundary, + adbSource, + adbBoundary, + cliBoundary, + mcpBoundary, + processBoundary, + acceptance, + composition, + evaluation, + ]; + const report = compareTestSelection(plan, inventory, inventory.map(passed)); + + expect(report.selected).toEqual( + expect.arrayContaining([ + sqliteSource, + sqliteBoundary, + cliBoundary, + mcpBoundary, + processBoundary, + acceptance, + composition, + evaluation, + ]), + ); + expect(report.omitted).toEqual([adbSource, adbBoundary]); + expect(report.complete).toBe(true); +}); + +it.each([ + ["unowned shared source", "src/application/Workflow.ts"], + ["fixture input", "tests/conformance/c/fixture.c"], + ["configuration", "vitest.config.ts"], + ["documentation", "README.md"], + ["CLI implementation", "src/cli/apktoolCommands.ts"], + ["MCP implementation", "src/server/registerSqliteTools.ts"], + ["process ownership", "src/process/ProcessOwnership.ts"], + ["acceptance test", acceptance], + ["composition test", composition], +])("uses full fallback for %s changes", (_description, path) => { + expect(planTestSelection([path], "pull_request", "fast")).toMatchObject({ + mode: "full", + owners: [], + changedTests: [], + }); +}); + +it("uses full fallback outside ordinary fast pull requests or without diff paths", () => { + expect( + planTestSelection(["src/sqlite/SqliteDatabaseProvider.ts"], "push", "fast") + .mode, + ).toBe("full"); + expect( + planTestSelection( + ["src/sqlite/SqliteDatabaseProvider.ts"], + "pull_request", + "full", + ).mode, + ).toBe("full"); + expect(planTestSelection([], "pull_request", "fast").mode).toBe("full"); +}); + +it("keeps new changed tests and falls back when a changed test was removed", () => { + const addedTest = "src/sqlite/NewDatabaseRule.test.ts"; + const candidate = planTestSelection([addedTest], "pull_request", "fast"); + expect(candidate.changedTests).toEqual([addedTest]); + const inventory = [addedTest, adbSource]; + expect( + compareTestSelection(candidate, inventory, inventory.map(passed)).selected, + ).toContain(addedTest); + + const removedTest = "src/sqlite/RemovedDatabaseRule.test.ts"; + const report = compareTestSelection( + planTestSelection([removedTest], "pull_request", "fast"), + [sqliteSource, adbSource], + [passed(sqliteSource), passed(adbSource)], + ); + expect(report.plan.mode).toBe("full"); + expect(report.selected).toEqual([adbSource, sqliteSource]); + expect(report.omitted).toEqual([]); +}); + +it("marks incomplete inventories and nonterminal outcomes as incomplete", () => { + const plan = planTestSelection( + ["src/sqlite/SqliteDatabaseProvider.ts"], + "pull_request", + "fast", + ); + const inventory = [sqliteSource, adbSource]; + const completeResults = inventory.map(passed); + + expect( + compareTestSelection(plan, inventory, [passed(sqliteSource)]).complete, + ).toBe(false); + expect( + compareTestSelection(plan, inventory, [ + ...completeResults, + passed("tests/evaluation/unexpected.test.ts"), + ]), + ).toMatchObject({ + complete: false, + unexpected: ["tests/evaluation/unexpected.test.ts"], + }); + expect( + compareTestSelection(plan, inventory, [ + ...completeResults, + passed(adbSource), + ]), + ).toMatchObject({ complete: false, duplicateFiles: 1 }); + for (const state of ["pending", "skipped"]) + expect( + compareTestSelection(plan, inventory, [ + passed(sqliteSource), + { name: adbSource, durationMs: 0, state }, + ]), + ).toMatchObject({ complete: false, unobserved: [adbSource] }); +}); + +it("reports a failure from an omitted test, including collection or module failures", () => { + const plan = planTestSelection( + ["src/sqlite/SqliteDatabaseProvider.ts"], + "pull_request", + "fast", + ); + const report = compareTestSelection( + plan, + [sqliteSource, adbSource], + [passed(sqliteSource), { name: adbSource, durationMs: 1, state: "failed" }], + ); + + expect(report.omitted).toContain(adbSource); + expect(report.missedFailures).toEqual([adbSource]); +}); + +it("rejects plans that name unowned owners or malformed changed tests", () => { + const plan = planTestSelection( + ["src/sqlite/SqliteDatabaseProvider.ts"], + "pull_request", + "fast", + ); + expect(() => + compareTestSelection( + { ...plan, owners: ["unknown"] }, + [sqliteSource], + [passed(sqliteSource)], + ), + ).toThrow("Invalid observational test selection plan"); + expect(() => + compareTestSelection( + { ...plan, changedTests: ["src/sqlite/not-a-test.ts"] }, + [sqliteSource], + [passed(sqliteSource)], + ), + ).toThrow("Invalid observational test selection plan"); +}); + +it("uses full fallback when a changed owner has no executable tests", () => { + const report = compareTestSelection( + planTestSelection( + ["src/sqlite/SqliteDatabaseProvider.ts"], + "pull_request", + "fast", + ), + [adbSource], + [passed(adbSource)], + ); + + expect(report.plan.mode).toBe("full"); + expect(report.omitted).toEqual([]); +}); diff --git a/tests/evaluation/package/nativeAotBuild.test.ts b/tests/evaluation/package/nativeAotBuild.test.ts new file mode 100644 index 000000000..6e71db42a --- /dev/null +++ b/tests/evaluation/package/nativeAotBuild.test.ts @@ -0,0 +1,90 @@ +import { join } from "node:path"; + +import { expect, it, vi } from "vitest"; + +import { buildNativeAotFixture } from "../../../scripts/lib/nativeaot-build.mjs"; + +const options = { + dotnet: "dotnet", + project: "fixture.csproj", + runtime: "win-x64", + output: "fixture-output", +}; + +it("restores the exact publish target before compiling without network restore", async () => { + const run = vi.fn<(command: string, args: string[]) => void>(); + await buildNativeAotFixture(run, options); + expect(run).toHaveBeenCalledTimes(2); + const restore = run.mock.calls[0]?.[1] ?? []; + const publish = run.mock.calls[1]?.[1] ?? []; + expect(restore[0]).toBe("restore"); + expect(publish[0]).toBe("publish"); + expect(publish).toContain("--no-restore"); + for (const argument of [ + options.project, + options.runtime, + "-p:Configuration=Release", + `-p:BaseIntermediateOutputPath=${join(options.output, "obj")}/`, + ]) { + expect(restore).toContain(argument); + expect(publish).toContain(argument); + } +}); + +it("retries without logging credential-bearing restore diagnostics", async () => { + const logged = vi.spyOn(console, "error").mockImplementation(() => {}); + const timeout = Object.assign( + new Error( + "dotnet restore ETIMEDOUT https://fixture-user:fixture-password@feed.invalid/v3/index.json", + ), + { + code: "ETIMEDOUT", + }, + ); + const run = vi + .fn<(command: string, args: string[]) => void>() + .mockImplementationOnce(() => { + throw timeout; + }); + try { + await buildNativeAotFixture(run, options); + expect( + logged.mock.calls.flat().every((value) => typeof value === "string"), + ).toBe(true); + expect(logged.mock.calls.flat().join("\n")).not.toContain( + "fixture-password", + ); + } finally { + logged.mockRestore(); + } + expect(run.mock.calls.map((call) => call[1][0])).toEqual([ + "restore", + "restore", + "publish", + ]); +}); + +it("stops after two restore failures and preserves the final diagnostic", async () => { + const failure = new Error("NuGet source unavailable"); + const run = vi.fn<(command: string, args: string[]) => void>(() => { + throw failure; + }); + await expect(buildNativeAotFixture(run, options)).rejects.toMatchObject({ + message: "NativeAOT dependency restore failed after two attempts", + cause: failure, + }); + expect(run).toHaveBeenCalledTimes(2); + expect(run.mock.calls.every((call) => call[1][0] === "restore")).toBe(true); +}); + +it("does not retry compilation failures", async () => { + const failure = new Error("Native compiler rejected the fixture"); + const run = vi + .fn<(command: string, args: string[]) => void>() + .mockImplementationOnce(() => {}) + .mockImplementationOnce(() => { + throw failure; + }); + await expect(buildNativeAotFixture(run, options)).rejects.toBe(failure); + expect(run).toHaveBeenCalledTimes(2); +}); diff --git a/tests/evaluation/package/nativeAotDiagnostics.test.ts b/tests/evaluation/package/nativeAotDiagnostics.test.ts new file mode 100644 index 000000000..f5b42a5ce --- /dev/null +++ b/tests/evaluation/package/nativeAotDiagnostics.test.ts @@ -0,0 +1,150 @@ +import { execFile } from "node:child_process"; +import { readdir, writeFile } from "node:fs/promises"; +import { join } from "node:path"; +import { fileURLToPath } from "node:url"; +import { promisify } from "node:util"; + +import { expect, it } from "vitest"; + +import { + nativeAotCommandError, + supportsNativeAotFixtureHost, +} from "../../../scripts/lib/nativeaot-build.mjs"; +import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js"; + +const generator = fileURLToPath( + new URL("../../../scripts/generate-nativeaot-fixtures.mjs", import.meta.url), +); + +const supportedHost = supportsNativeAotFixtureHost( + process.platform, + process.arch, +); + +it.skipIf(!supportedHost).each(["restore", "publish"])( + "redacts authenticated feed URLs from the uncaught %s diagnostic", + async (operation) => { + const directory = await createTestTempDirectory( + "rea-nativeaot-diagnostic-", + ); + const hook = join(directory, "child-output.cjs"); + await writeFile( + hook, + ` +const child = require("node:child_process"); +child.spawnSync = (_command, args) => { + if (args[0] === "--version") return { status: 0, stdout: "8.0.416\\n", stderr: "" }; + if (args[0] === ${JSON.stringify(operation)}) return { + status: 1, + error: new Error("failed HTTPS://error-user:error-secret@feed.invalid/v3/index.json"), + stdout: "NU1301 https://stdout-user:stdout-secret@feed.invalid/v3/index.json\\n", + stderr: "source https://stderr-user:stderr-secret%40suffix@feed.invalid/v3/index.json\\nkeep https://feed.invalid/path/user@name?label=token-name\\n" + }; + return { status: 0, stdout: "", stderr: "" }; +}; +require("node:module").syncBuiltinESMExports(); +`, + "utf8", + ); + const failure = await promisify(execFile)( + process.execPath, + ["--require", hook, generator], + { + env: { + ...process.env, + REA_NATIVEAOT_FIXTURE_ROOT: join(directory, "output"), + }, + timeout: 15_000, + }, + ).then( + () => { + throw new Error("Expected fixture generation to fail"); + }, + (error: { stderr: string; code: number }) => error, + ); + expect(failure.code).toBe(1); + for (const secret of [ + "error-user", + "error-secret", + "stdout-user", + "stdout-secret", + "stderr-user", + "stderr-secret", + ]) + expect(failure.stderr).not.toContain(secret); + expect(failure.stderr).toContain("NU1301"); + expect(failure.stderr).toContain("feed.invalid/v3/index.json"); + expect(failure.stderr).toContain( + "https://feed.invalid/path/user@name?label=token-name", + ); + if (operation === "restore") { + expect(failure.stderr).toContain("attempt 2/2"); + expect(failure.stderr).toContain("failed after two attempts"); + expect(failure.stderr).toContain("[cause]"); + } + }, +); + +it.skipIf(supportedHost)( + "refuses unsupported fixture hosts before tooling or output creation", + async () => { + const directory = await createTestTempDirectory("rea-nativeaot-host-"); + const hook = join(directory, "unexpected-child.cjs"); + await writeFile( + hook, + `const child = require("node:child_process"); +child.spawnSync = () => { throw new Error("Unexpected fixture tooling invocation"); }; +require("node:module").syncBuiltinESMExports(); +`, + "utf8", + ); + const failure = await promisify(execFile)( + process.execPath, + ["--require", hook, generator], + { + env: { + ...process.env, + REA_NATIVEAOT_FIXTURE_ROOT: join(directory, "output"), + }, + timeout: 15_000, + }, + ).then( + () => { + throw new Error("Expected unsupported fixture host refusal"); + }, + (error: { stderr: string; code: number }) => error, + ); + expect(failure.code).toBe(1); + expect(failure.stderr).toContain("requires Linux or Windows x64"); + expect(failure.stderr).not.toContain( + "Unexpected fixture tooling invocation", + ); + expect(await readdir(directory)).toEqual(["unexpected-child.cjs"]); + }, +); + +it("preserves diagnostics without transport authentication exactly", () => { + const error = nativeAotCommandError( + "C:/token projects/dotnet.exe", + "restore", + { + status: 1, + stdout: "NU1301 https://feed.invalid/user@name?label=password\n", + stderr: "project C:/token projects/fixture.csproj unavailable", + }, + ); + expect(error.message).toBe( + "NativeAOT fixture lane requires/action failed C:/token projects/dotnet.exe restore: exit 1\nNU1301 https://feed.invalid/user@name?label=password\nproject C:/token projects/fixture.csproj unavailable", + ); + expect(error.cause).toBeUndefined(); +}); + +it("treats HTTP backslashes as path separators rather than authentication", () => { + const output = String.raw`https://feed.invalid\path\user@name`; + expect(new URL(output).username).toBe(""); + const error = nativeAotCommandError("dotnet", "restore", { + status: 1, + stdout: output, + }); + expect(error.message).toContain(output); +}); diff --git a/tests/fixtures/native-macos/lipo-same-cpu/README.md b/tests/fixtures/native-macos/lipo-same-cpu/README.md new file mode 100644 index 000000000..d376e3b5d --- /dev/null +++ b/tests/fixtures/native-macos/lipo-same-cpu/README.md @@ -0,0 +1,19 @@ +# Universal Mach-O captures whose slices share one CPU type + +Captured on macOS 27.0.1 (26A434), arm64, from two system executables whose +FAT slices all use `CPU_TYPE_ARM64`: + +```sh +lipo -detailed_info /System/Applications/Calculator.app/Contents/MacOS/Calculator > calculator.txt +lipo -detailed_info /System/Library/CoreServices/ShortcutDroplet.app/Contents/MacOS/ShortcutDroplet > shortcut-droplet.txt +``` + +Calculator holds `arm64e` (subtype `0x80000002`) and `arm64e.x1` (subtype +`0x8000000c`); ShortcutDroplet holds `arm64` (subtype `0`) and `arm64e.x1`. +Target admission names both files by the single CPU family `arm64`, while lipo +lists two slices. + +The executable path on the `Fat header in:` line was replaced with `fixture`, +and trailing whitespace (lipo prints `capabilities ` for a slice without +capabilities) and the final blank line were removed. Tool fields are otherwise +unchanged. diff --git a/tests/fixtures/native-macos/lipo-same-cpu/calculator.txt b/tests/fixtures/native-macos/lipo-same-cpu/calculator.txt new file mode 100644 index 000000000..8e90b4902 --- /dev/null +++ b/tests/fixtures/native-macos/lipo-same-cpu/calculator.txt @@ -0,0 +1,17 @@ +Fat header in: fixture +fat_magic 0xcafebabe +nfat_arch 2 +architecture arm64e + cputype CPU_TYPE_ARM64 + cpusubtype CPU_SUBTYPE_ARM64E + capabilities PTR_AUTH_VERSION USERSPACE 0 + offset 16384 + size 1727552 + align 2^14 (16384) +architecture arm64e.x1 + cputype CPU_TYPE_ARM64 + cpusubtype unknown arm64 cpusubtype + capabilities PTR_AUTH_VERSION USERSPACE 0 + offset 1753088 + size 1711088 + align 2^14 (16384) diff --git a/tests/fixtures/native-macos/lipo-same-cpu/shortcut-droplet.txt b/tests/fixtures/native-macos/lipo-same-cpu/shortcut-droplet.txt new file mode 100644 index 000000000..252ff7234 --- /dev/null +++ b/tests/fixtures/native-macos/lipo-same-cpu/shortcut-droplet.txt @@ -0,0 +1,17 @@ +Fat header in: fixture +fat_magic 0xcafebabe +nfat_arch 2 +architecture arm64 + cputype CPU_TYPE_ARM64 + cpusubtype CPU_SUBTYPE_ARM64_ALL + capabilities + offset 16384 + size 52000 + align 2^14 (16384) +architecture arm64e.x1 + cputype CPU_TYPE_ARM64 + cpusubtype unknown arm64 cpusubtype + capabilities PTR_AUTH_VERSION USERSPACE 0 + offset 81920 + size 52000 + align 2^14 (16384) diff --git a/website/README.md b/website/README.md index b7a159570..f09c7f603 100644 --- a/website/README.md +++ b/website/README.md @@ -131,6 +131,7 @@ describe its recorded investigation; update them only when repeating that work. - `public/showcase/index.html`: the case-study index. - `public/blog/index.html`: articles about reconstruction methods, ports, mods and reverse engineering. - `public/blog/touhou-reconstruction/index.html`: a personal essay about agent autonomy, oracle quality, knowledge carried between TH08 and TH095, PC-98 TH04, and the path from exact reconstruction to readable source and modern ports. +- `public/blog/reverse-engineering-models/index.html`: an essay on general models, compiler specialization and learning useful reconstruction experiments, with historical evidence from TH08, TH095, TH04 and TH09. Model attribution and verification scope are in [evidence/reverse-engineering-models.md](evidence/reverse-engineering-models.md). - `public/showcase/aegis/index.html`: Aegis's Android login-code calculation, with an adjustable clock and reference checks. - `public/showcase/dx-ball/index.html`: sound-pan investigation and project status. - `public/showcase/notion/index.html`: Notion's Electron clipboard bridge and rich clipboard format. diff --git a/website/evidence/reverse-engineering-models.md b/website/evidence/reverse-engineering-models.md new file mode 100644 index 000000000..069d6eea3 --- /dev/null +++ b/website/evidence/reverse-engineering-models.md @@ -0,0 +1,166 @@ +# General models and specialist models: article evidence + +Supporting record for `public/blog/reverse-engineering-models/index.html`. +The article is published from the English source and translated through the +website's gettext catalogs. + +## Research scope + +Repository history, maintained source and recorded comparison notes were reviewed +on 13 October 2026. This research did not run game targets, compile reconstruction +candidates or repeat historical runtime checks. Public commit availability was +checked through GitHub CLI. + +The evidence describes specific historical functions and their recorded checks. +Source presence, compiler exactness, complete-product builds and runtime agreement +remain distinct. The proposed specialist/RL comparisons are future experiments; +no trained specialist was evaluated for this article. + +## Model attribution + +- The project operator identifies `gpt-dots` as **GPT-6-Astra**. +- `gpt-web` is a changing label for the model used at the time. The operator + describes then-latest models, usually xhigh, commonly GPT-5.6-Sol earlier and + GPT-6-Sol recently. Do not assign all such commits a single model or infer + individual identities from a release date. +- Explicit `gpt-6-sol` and `gpt-6.1-sol` subjects establish the recorded names. + Per-run reasoning effort and full budgets are not uniformly recorded. +- `gpt-6-luna-max` records GPT-6-Luna and max effort. It does not establish + parameter count or specialist training. + +Later sessions inherited earlier source, diagnostics and failed experiments. +Historical before/after closures support the essay's questions; they are not +controlled estimates of model-size effects. + +## TH09 Type18/24 attack update + +Earlier source-context review: +[GPT-6-Sol, 26 September](https://github.com/N0zoM1z0/th09/commit/de63c0f9121963f3a6b1ab5471c4878625fd3425). +Closing reconstruction: +[GPT-6.1-Sol, 10 October](https://github.com/N0zoM1z0/th09/commit/52929ed7c299f1a5f29cc13964e22510145fd616). + +The earlier candidate was 1,435 bytes against a 1,436-byte target. Matching the +overall frame size concealed different homes for returned vectors and real +collision storage. Declaration and helper-visibility controls did not close it. + +The closing session introduces an ordinary XYZ destination assignment, consumes +real returned vectors directly and groups six actual publication/rotation +operations into one comma-sequenced full expression. Keeping the real collision +point at function scope preserves separate storage. The seventh warm candidate +matches, followed by a maintained-path canonical cold comparison of all 1,436 +bytes and 44 encoded fields. Original class/source spelling and later runtime +gates remain separate. + +The article's four-row table groups selected lessons from seven candidates. It +does not enumerate every build or reproduce a complete source listing. + +## TH09 Front callback + +Earlier diagnostic checkpoint: +[GPT-6.1-Sol, 2 October](https://github.com/N0zoM1z0/th09/commit/f8d12d72aaf02212ee1b585a8f3f86d7ed000269). +Full graph closure: +[GPT-6-Astra (`gpt-dots`), 6 October](https://github.com/N0zoM1z0/th09/commit/da33a646221198ceb7f3df2b96e2ca0e9b2f705f). +Accepted replay: +[6 October follow-up](https://github.com/N0zoM1z0/th09/commit/5f825b28a862f8e1a6d4aea2f78a42f04c09a1c0). + +The earlier maintained owner was 1,510 bytes versus the 1,491-byte target. Its +prefix and suffix matched only as independently positioned diagnostic regions; +they did not establish a complete-function match. + +A common outer continuation places completion and frame dispatch in complementary +arms with one final frame increment/return. Within this graph, the side/stage +decision recovers target block sharing. The record establishes the complete +1,491-byte owner, 107 independently bound fields, 384 instructions and 42 calls. +The follow-up records accepted forced-recompile replay for `da33a646`. +Bounded trace models are static checks, not game-runtime validation. + +## TH095 identifier-bucket reuse + +[Supervisor::LoadDat, 2 September](https://github.com/N0zoM1z0/th095/commit/26bb64bdb093a13f73abd0ee8ae7ce199ee4658f). + +Under observed VC7.1 build 3077, declaration order alone did not recover the real +local homes. Earlier background work established useful identifier buckets. +Backing the real file-size scalar with `averagedPanLocal12` places it at +`EBP-0x04` and the genuine 128-byte buffer at `EBP-0x88`. All 151 bytes and 15 +relocations close. + +This is compiler-context evidence. It does not establish a universal C++ rule +or uniquely recover the original author's variable name. The `gpt-web` label +does not identify this run's model individually. + +## TH09 Luna enemy-spawn closure + +[GPT-6-Luna-max, 27 September](https://github.com/N0zoM1z0/th09/commit/1eb843383941d00065622a9e353146c4bb96979e). + +An ordinary loop with `continue`/`break`, branch-local RunEcl failure handling +and a shared success tail closes the 373-byte owner. TH08 source supplies the +source-family hypothesis; TH09 establishes the bounds, fields, ABI and callees. +Two independent cold builds and canonical replay are recorded. + +The earlier stable 361-byte candidate is `gpt-web`, with an individually +unresolved model identity. This case demonstrates a useful discovery across +model tiers, not a measured specialist or smaller-parameter advantage. + +## TH04 compiler diversity + +[Player MAIN_0 cohort, 15 September](https://github.com/N0zoM1z0/th04/commit/6dce0a79d5b931f0e2a08475b90e0c33d2321b98). + +Natural Turbo C++ 4.0J source produces a 629-byte update/miss contribution and a +334-byte renderer. Expression lifetimes, branch-local stores, declaration order +and a shared firing tail matter. Correct physical linker order avoids an extra +alignment byte. The recorded focused and aggregate replays cover 129 and 208 +owners respectively. These are historical owned-extent checks; this checkpoint +does not establish whole-game execution. + +TH08 uses VC7, while TH095/TH09 use VC7.1. Avoid treating every game's source +patterns as output from the same compiler. Shared game authorship supplies a +prior; target-local evidence validates an actual transfer. + +## TH08 numerical investigation + +[Polar motion and x87 behavior, 13 October](https://github.com/N0zoM1z0/th08/commit/af9cb1d3e839b15a78b47ac1701506083cc82847). + +A collision divergence at stage 2 frame 6,825 leads back to a one-ULP +displacement difference at frame 5,573. Historical CRT wrappers retain a wider +x87 return despite storing a rounded float. A distinct i386 case involves x87 +precision-control state. The record includes field probes and replay checks for +specified scenarios. Several preceding investigations use the same model; this +is breadth-of-investigation evidence, not a model-switch comparison. + +## TH08 floating-literal oracle repair + +[Repository-wide audit, 2 September](https://github.com/N0zoM1z0/th08/commit/a393f400786e4cc6cbb1000af0dad3276da12c78). + +Literal payload checks previously depended on optional explicit `data_hex` +attestation. The fix decodes and target-checks every VC7 `__real@...` relocation. +The follow-up audits 1,548 relocations and corrects 12 stale rows in five already +accepted units. One source change corrects a bullet-spread increment from +`1.0f` to `32.0f`. + +Affected-unit replay and a complete 1,106-unit cold replay are recorded after +repair. This defect is separate from the later one-ULP numerical investigation. +The RL consequence in the article is an inference: a reward based on the earlier +check could reinforce wrong source. The record does not describe an actual RL +exploit or trained model doing so. + +## TH09 target-sized replay-save candidate + +[Replay-save closure, 2 October](https://github.com/N0zoM1z0/th09/commit/ab72fd77728293fc0beacfc656ca701b0e266016). + +The earlier candidate already had the target's 1,825-byte length but 467 complete +comparison differences. Shared index identity, loop structure and the real +cancel/overwrite continuation close the complete owner. The example supports +using size as a diagnostic rather than final acceptance. + +## Related research + +The article links these primary sources: + +- [LLM4Decompile, EMNLP 2024](https://aclanthology.org/2024.emnlp-main.203/). +- [AutoDecompiler, June 2026 preprint](https://arxiv.org/html/2606.16162v1). +- [When LLM Decompilers Recompile More and Preserve Less, September 2026 preprint](https://arxiv.org/html/2609.05370v1). + +These works concern specialized decompilation, feedback-based refinement and +functional checking. Their published setups do not establish a winner for the +article's proposed historical-compiler reconstruction experiment. Preserve that +objective distinction when expanding the discussion. diff --git a/website/locales/ar/messages.po b/website/locales/ar/messages.po index 329f0cd96..daaa1d33a 100644 --- a/website/locales/ar/messages.po +++ b/website/locales/ar/messages.po @@ -32,18 +32,18 @@ msgid "Thoughts on reverse engineering." msgstr "أفكار حول الهندسة العكسية." #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "لعبة إعادة الإعمار{ph0}مقال" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "الثورة الصناعية في الهندسة العكسية" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " @@ -52,19 +52,20 @@ msgstr "" "ما دليل إعادة تعمير TH08, TH095 و TH04 علمني عن وكلاء والتحقق المعرفة أن " "المركبات عبر المشاريع." -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "اقرأ المقال" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "بواسطة N0zoM1z0 * 10 أكتوبر 2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -100,6 +101,8 @@ msgstr "" "العفو الدولية." #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -134,6 +137,7 @@ msgid "" msgstr "REA - اكتشف كيف يعمل البرنامج. الهندسة العكسية مع مساعدك البرمجي." #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -154,6 +158,7 @@ msgid "REA home" msgstr "الصفحة الرئيسية لـ REA" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -174,6 +179,7 @@ msgid "Main navigation" msgstr "التنقل الرئيسي" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -194,6 +200,7 @@ msgid "REA on GitHub" msgstr "REA على GitHub" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -214,6 +221,7 @@ msgid "Join REA on Discord" msgstr "انضم إلى REA على Discord" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -233,7 +241,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "تابع REA على X" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "العودة للأعلى" @@ -11384,6 +11392,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "نفس التباعد: 256 1 16 = 16 وحدة زاوية = 22.5°" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -11404,6 +11413,7 @@ msgid "Showcases" msgstr "أمثلة عملية" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -11424,6 +11434,7 @@ msgid "Blog" msgstr "المدونة" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -11444,6 +11455,7 @@ msgid "Get started" msgstr "ابدأ هنا" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -11463,7 +11475,8 @@ msgctxt "shared" msgid "Guides" msgstr "الأدلة" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -11483,7 +11496,8 @@ msgctxt "shared" msgid "Source" msgstr "الكود المصدري" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -11503,7 +11517,8 @@ msgctxt "shared" msgid "MIT license" msgstr "رخصة MIT" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -11523,7 +11538,8 @@ msgctxt "shared" msgid "Join the community" msgstr "انضم إلى المجتمع" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -12478,6 +12494,1318 @@ msgstr "" "تسجيل في REA دون اتصال، أو اربط خادم MCP في Everywhere لفحص حركة المرور " "المسجلة مع وكيلك." +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "نماذج متخصصة{ph0}مقال" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "هل تحتاج الهندسة العكسية إلى نموذج أكبر؟" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "" +"أفكار من إعادة بناء Touhou حول النماذج العامة والمتخصصة والتعلم من نتائج " +"المُصرّف." + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "بواسطة N0zoM1z0 · 13 أكتوبر 2026" + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "تخطي إلى المحتوى" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "" +"{ph0}الصفحة الرئيسية{ph1} / {ph2}المدونة{ph3} / النماذج والهندسة العكسية" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "مقال" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "هل تحتاج الهندسة العكسية إلى نموذج أكبر؟" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "بواسطة N0zoM1z0 · 13 أكتوبر 2026" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "أهم الأفكار" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "" +"{ph0}تؤثر قدرة النموذج على الفرضيات التي يمكن أن يقترحها وكيل الذكاء " +"الاصطناعي.{ph1} قامت الجلسات اللاحقة بحل المشكلات التي تركها العمل السابق " +"دون حل." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "" +"{ph0}يقدم المترجم المألوف أنماطًا محددة لنموذج متخصص للتعلم.{ph1} تعتمد بعض " +"المطابقات الدقيقة لرمز الآلة على أنماط محددة من كود المصدر قابلة لإعادة " +"الاستخدام." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "" +"{ph0}قم بتضمين معرفة المستودع في مقارنة عادلة.{ph1} قد يحتوي النموذج الأصغر " +"الذي يتمتع باسترجاع جيد للمعرفة على معلومات كافية لإحراز تقدم." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "" +"{ph0}قم بتدريب النموذج على اختيار التجربة المفيدة التالية، واختبار أداة " +"التحقق الخاص به.{ph1} تكون التعليقات مفيدة فقط إلى الحد الذي يتحقق فيه " +"المدقق من الأشياء الصحيحة." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "" +"{ph0}قم بتقييم نتائج إعادة بناء الشيفرة التي تم التحقق منها جنبًا إلى جنب مع" +" الوقت والتكلفة.{ph1} هذا ما أريد قياسه لسير عمل وكيل الذكاء الاصطناعي " +"الكامل." + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "في هذه المقالة" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}ما الذي غيّرته النماذج الأقوى؟{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}لماذا التخصص؟{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}أين ينبغي تخزين هذه التجربة؟{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}تعلم التجربة المفيدة التالية{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}الهندسة العكسية والتعلم المعزز{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}عندما يكون أداة التحقق خاطئًا{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}مقارنة تستحق التشغيل{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}ما هو نوع وكيل الذكاء الاصطناعي الذي يشير إليه هذا؟{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "ما الذي غيّرته النماذج الأقوى؟" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"منذ أغسطس 2026، كنت أستكشف مقدار الهندسة العكسية التي يمكن للوكيل تنفيذها من" +" خلال الوصول إلى البرنامج وطريقة التحقق من عمله. معظم خبرتي تأتي من إعادة " +"بناء الألعاب، وخاصة Touhou. وبما أنني قمت بتغيير النماذج، فقد احتفظت " +"المستودعات بسجل لما تمكنت كل جلسة من استعادته." + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"يهدف كثير من هذا العمل إلى إعادة بناء دقيقة: نترجم الشيفرة المصدرية التي " +"نحتفظ بها باستخدام أدوات من تلك الحقبة بإصدارات ثابتة، ثم نتحقق من أنها تعيد" +" إنتاج الدالة المستهدفة. عندما يحل نموذج أحدث مشكلة تعثر عندها العمل السابق،" +" تكشف تغييرات الشيفرة ما الذي أتاح هذا التقدم." + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "تحتاج المتغيرات المؤقتة إلى عمر متداخل" + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"تمت إعادة بناء الكثير من منطق دالة الهجوم TH09 بالفعل، لكن المترجم ما زال " +"يخزن النتائج المؤقتة بشكل مختلف عن الأصل. وكانت المشكلة المتبقية هي المدة " +"التي تحتاجها تلك النتائج للبقاء على قيد الحياة، ومتى يمكن إعادة استخدام " +"مخزونها." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"أبلغ {ph0}GPT-6-Sol سجل الجلسة{ph1} عن عدم التطابق هذا بعد اختبار العديد من " +"ترتيبات كود المصدر العادية. عندما فحص {ph2}GPT-6.1-Sol المشكلة مرة " +"أخرى{ph3}، اقترح فرضية مفيدة حول عمر هذه المتغيرات المؤقتة." + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"أنتجت الوظيفة نتائج مؤقتة ونسختها في مواضع الرسوم المتحركة. في لغة C++، تظل " +"النتيجة المؤقتة حية حتى انتهاء التعبير الذي يستخدمها. يؤدي تجميع العمليات " +"الحقيقية في تعبير واحد إلى إبقاء هذه النتائج حية معًا، لذلك لم يعد بإمكان " +"المترجم إعادة استخدام نفس وحدة التخزين لجميعها." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"لا تزال إحدى النتائج مشتركة في مساحة التخزين مع القيمة المستخدمة لاحقًا " +"للتحقق من التضارب. إن إعطاء هذه القيمة مدى الحياة الخاص بها أدى إلى حل " +"التداخل المتبقي. وبعد عدة تجارب مستهدفة، {ph0}أكدت إعادة الترجمة النظيفة من " +"المصدر أن الوظيفة الكاملة مطابقة{ph1}." + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"أنا مهتم بكيفية دعم الاكتشاف والاختبارات لبعضهما البعض. أعطت الفرضية " +"المتعلقة بعمر الكائنات المؤقتة لعامل الذكاء الاصطناعي اتجاهًا جديدًا. ساعدت " +"تعليقات المترجم في تحسين هذه الفرضية إلى ترتيب كود المصدر المطابق." + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "رسم بياني مختلف للتحكم في التدفق" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"توضح وظيفة TH09 الثانية سبب أهمية هذا الاتجاه الجديد. وهنا، كانت العقبة هي " +"كيفية مشاركة العديد من الفروع لعملها النهائي. يحتوي العمل السابق لـ " +"{ph0}GPT-6.1-Sol{ph1} على أجزاء من الدالة متطابقة، ولكن لا تزال الفروع متصلة" +" بشكل مختلف عن الأصل." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}غيّر GPT-6-Astra الرسم البياني المحيط لتدفق التحكم{ph1}. أصبحت المسارات" +" الرئيسية تؤدي إلى تحديث أخير وعودة مشتركين. بهذه البنية، دمج المترجم " +"البرمجي الفروع كما في الأصل. تطابقت الدالة كاملة، وأكد ذلك {ph2}فحص مستقل " +"لإعادة البناء{ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}أدى تغيير التمثيل إلى فتح مساحة بحث أكثر إنتاجية.{ph1} تمنحني كلتا " +"الحالتين سببًا لأخذ إمكانات النموذج العامة على محمل الجد: يمكن للوكيل " +"الاستمرار في تجربة الاختلافات المحلية لفترة طويلة قبل العثور على طريقة أفضل " +"للتعبير عن العمل المحيط." + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"في الوقت نفسه، بدأت الجلسات اللاحقة بمصادر سابقة وإخفاقات مسجلة. وكان هذا " +"العمل المتراكم جزءًا من مصلحتهم. يتيح لنا التاريخ فحص الاكتشافات وفحصها؛ ومن" +" شأن المقارنة الخاضعة للرقابة أن تساعد في فصل تأثير النموذج عن الخبرة التي " +"ورثها." + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"وهذا ما يجعل السؤال مثيرًا للاهتمام بالنسبة لي. جاء بعض التقدم من إيجاد " +"تمثيل جديد. تضمن الكثير من العمل المتبقي اختبار ترتيبات مختلفة لشفرة المصدر " +"مقابل مترجم مألوف. كم من هذا يتطلب قدرة تفكير واسعة النطاق؟ ما مقدار ما يمكن" +" أن يتعلمه النموذج من خلال العمل المتكرر مع هذا المترجم والكود؟" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "لماذا قد يكون نموذج الذكاء الاصطناعي المتخصص ناجحًا؟" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"Touhou يعطينا سببًا ملموسًا لتوقع أن تساعدنا هذه التجربة. الكثير من رموز " +"اللعبة تأتي من نفس المؤلف، ZUN، لذا فإن العادات المتكررة هي افتراض بداية " +"معقول. تدعم المستودعات ذلك بأمثلة مفيدة: الحلقات ذات الصلة والترتيبات " +"المساعدة قدمت فرضيات عبر الألعاب." + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "" +"تصبح أنماط المصدر هذه أكثر تحديدًا عندما نقوم بتضمين المترجم. ضمن إصدار معين" +" ومجموعة من الخيارات، يمكن أن تؤدي التغييرات الصغيرة في المصدر إلى اختلافات " +"متكررة في كود الجهاز. بعض هذه الاختلافات غامضة بشكل مدهش." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"في TH095، على سبيل المثال، {ph0}حتى اسم المتغير المحلي يمكن أن يؤثر على مكان" +" تخزينه VC7.1{ph1}. لم يؤدي نقل إعلانه إلى حل تخطيط التخزين. ومع ذلك، كشفت " +"وظيفة خلفية سابقة عن نمط تسمية أثر على اختيار المترجم. وقد اقترح ذلك فرضية " +"واعدة أكثر بشأن {ph2}إعادة بناء {ph3}{ph4}." + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "" +"أدت إعادة استخدام هذا النمط لمتغير حجم الملف إلى إنتاج التخطيط المطلوب دون " +"إضافة مساحة تخزين. ثم تمت مطابقة الوظيفة الكاملة." + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "" +"هذه تفاصيل محددة جدًا قد لا يعرفها نموذج الذكاء الاصطناعي للأغراض العامة " +"عندما يواجه المشكلة لأول مرة. يمكن للنموذج المتخصص لهذا المترجم أن يرى " +"العديد من هذه الحالات ويتعرف على اختلافات التعليمات البرمجية المصدر التي " +"تستحق الاختبار أولاً." + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"تكون الفرصة واضحة بشكل خاص في مشاكل المطابقة النهائية حيث نفهم السلوك " +"بالفعل. ثم نسأل عن ترتيب التعليمات البرمجية المصدر العادي الذي يحوله هذا " +"المترجم إلى التعليمات المرصودة. يمكن أن يساعد التخصص النموذج على اقتراح تلك " +"الأشكال بشكل أكثر كفاءة، في حين أن الهدف لا يزال يحدد الفرضيات التي ستبقى." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"يجب أن تحتفظ الأنماط بسياقها. يستخدم TH08 إصدارًا من Visual C++ أقدم مما " +"يستخدمه TH095 وTH09. أما TH04 فيستخدم مُترجمًا برمجيًا آخر من حقبة DOS، وقد " +"احتاجت {ph0}إعادة بناء شيفرة اللاعب{ph1} إلى فرضيات مختلفة عن أنماط الشيفرة " +"وكيفية ربطها في ملف تنفيذي. وحدة المؤلف تعطينا توقعًا أوليًا، لكن كل هدف " +"يبين إن كان ينطبق. وعلى النموذج المتخصص تعلم هذه الفروق." + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "أين ينبغي تخزين هذه التجربة؟" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"قبل أن أقرر تعليم هذه الأنماط للنموذج، سأراجع المعرفة التي نحفظها بالفعل في " +"المستودع. في {ph0}المقال السابق{ph1} كتبت عن المستودع وهو يصبح الذاكرة " +"العاملة للمشروع. تتضمن هذه الذاكرة ما تعلمناه عن سلوك المترجم البرمجي، مع " +"الشيفرة والتجارب الفاشلة التي جعلت تلك المعرفة مفيدة." + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"من خلال استرداد هذا السجل، يمكن للوكيل البدء بنتيجة معروفة وفحص كيفية وصولنا" +" إليها. ويمكنه أيضًا تجنب البدائل التي فشلت بالفعل في نفس السياق. تتحسن نقطة" +" البداية دون تغيير معلمات النموذج المدربة." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"أثناء إعادة بناء وظيفة TH09 لإنشاء الأعداء، أخذت جلسة {ph0}GPT-6-Luna-" +"max{ph1} فرضية من كود مصدر TH08 ذي الصلة. اقترح هذا الكود السابق كيفية تنظيم" +" الحلقة والتعامل مع حالات الفشل بداخلها. قدمت أدلة TH09 الخاصة التفاصيل " +"الخاصة باللعبة. أكدت عمليات إعادة البناء من المصدر أن الوظيفة الكاملة " +"متطابقة." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}\"النموذج لم يكن يعرف هذه الخاصية المحددة للمترجم البرمجي\" و\"النموذج " +"لم يستطع استخدامها\" مشكلتان مختلفتان.{ph1} قد يحل استرجاع المعرفة المشكلة " +"الأولى، لكن تحويلها إلى شيفرة مرشحة مفيدة يحتاج إلى عمل. وإذا فشلت الشيفرة " +"المرشحة، فعلى النموذج أن يقرر ما تعنيه النتيجة لمحاولته التالية. معرفة النمط" +" المناسب هي بداية العملية فقط." + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"لهذا السبب، سأقوم بتضمين نموذج ذكاء اصطناعي أصغر حجمًا للأغراض العامة مع " +"استرجاع جيد في أي مقارنة. إن منحها نفس مكتبة الخبرة من شأنه أن يساعدنا في " +"تحديد ما يضيفه التدريب: جيل أفضل للمرشحين، أو قرارات أفضل بعد التعليقات، أو " +"كليهما." + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "تعلم التجربة المفيدة التالية" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"تلك القرارات بعد ردود الفعل هي أكثر ما أرغب في دراسته. في إعادة البناء " +"الوكيل، يقترح النموذج تفسيرًا ويختبره مقابل البرنامج. وحتى عندما يفشل الكود " +"المصدري المرشح، فإن النتيجة يمكن أن تضيق الاحتمالات المتبقية وتقترح تجربة " +"تالية أكثر فائدة." + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "" +"خذ بعين الاعتبار مثال النتائج المؤقتة مرة أخرى. يُظهر مصدره النهائي الترتيب " +"الذي نجح، لكن المسار إلى هذا المصدر يحتوي على مزيد من المعلومات. ساعدت كل " +"تجربة من التجارب التالية في تحديد ما لا يزال بحاجة إلى التغيير." + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "تجربة" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "ماذا علمتنا نتيجته" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "جرب طريقة مختلفة لنسخ النتائج" + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "يتغير رمز النسخ، لكن الوظيفة لا تزال مختلفة." + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "استخدم القيم التي تم إرجاعها مباشرة" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "يتبع النسخ النمط الأصلي، لكن التخزين المؤقت لا يزال مختلفًا." + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "إبقاء كافة المتغيرات المؤقتة صالحة في نفس الوقت" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "" +"يحصلون على مساحة تخزين منفصلة، ولكن لا يزال هناك تداخل مع قيمة يتم استخدامها" +" لاحقًا للتحقق من التصادم." + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "احتفظ بقيمة التحقق من التصادم منفصلة" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "تؤكد إعادة الترجمة النظيفة من المصدر التطابق الكامل." + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "" +"تجارب مختارة من إعادة بناء وظيفة الهجوم أعلاه، مجمعة حسب ما علمتنا إياه." + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"يمكن لسجل التدريب الذي يحتفظ بهذا التسلسل أن يعلم أكثر من المصدر النهائي " +"وحده. فهو يربط كل تغيير مقترح بالنتيجة الملحوظة والقرار التالي. إن الاحتفاظ " +"بالتغيرات غير الفعالة أمر مهم أيضًا: فهي تخبر وكيلًا لاحقًا بالفرضيات التي " +"تم اختبارها بالفعل في هذا السياق." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}أريد أن يتعلم النموذج كيفية استخدام التعليقات.{ph1} النتيجة المحايدة هي" +" سبب لإعادة النظر في الشكل؛ قد يشير عدم التطابق المتغير إلى سبب آخر. عندما " +"تتوقف التعديلات المحلية عن تقديم المعلومات، يجب أن يكون الوكيل قادرًا على " +"إعادة النظر في تمثيل المصدر أو فحص الأدلة مرة أخرى." + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"تعلم هذه الاختيارات يتطلب الاستقلالية. أحيانًا تكون الخطوة الأنسب فحص دالة " +"أخرى تستدعي هذه الدالة بدل ترجمة تعديل جديد. فرض سلسلة جامدة من إعادة " +"الكتابة يلغي هذا الاختيار ومعه جزءًا من السلوك الذي نريد أن يتعلمه النموذج." + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "لماذا تعتبر الهندسة العكسية مثيرة للاهتمام للتعلم المعزز" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"توفر إعادة البناء ذات النطاق المحدد بيئة عملية لدراسة هذه القرارات. بعد " +"تثبيت إصدارات الهدف والمترجم البرمجي، تعطي تجارب كثيرة على الشيفرة ملاحظات " +"سريعة وقابلة للتكرار. يستطيع الوكيل ترجمة شيفرة مرشحة وفحص الفروق ثم اختيار " +"الخطوة التالية." + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"يمكن للتعلم المعزز تدريب عملية صنع القرار من خلال ردود الفعل التي تتلقاها. " +"يمنحنا المرشح الذي يتم قبوله عن طريق فحص محدد نتيجة ملموسة، في حين يتيح لنا " +"تسلسل المحاولات ملاحظة مقدار العمل الذي استغرقه الوصول إلى هذه النتيجة." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"هناك أبحاث تدعم هذا الاتجاه بالفعل. يدرس {ph0}LLM4Decompile{ph1} نماذج " +"متخصصة في استعادة الشيفرة المصدرية من البرامج المترجمة. ويستخدم " +"{ph2}AutoDecompiler{ph3} نتائج الترجمة والتنفيذ لتدريب التحسين عبر جولات " +"متعددة. تركز هذه الدراسات على استعادة سلوك البرنامج. سأستخدمها نقطة بداية " +"لمهمة قريبة: إيجاد شيفرة تنتج مخرجات مطابقة لمترجم برمجي تاريخي." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"للوصول إلى مثل هذه المهمة المحددة جيدًا، قد نحتاج أولاً إلى تحديد الموارد " +"التي تمتلكها الوظيفة أو ابتكار طريقة جديدة لملاحظة سلوك البرنامج أثناء " +"تشغيله. في TH08، على سبيل المثال، {ph0}أدى اختلاف التصادم إلى كيفية تعامل " +"البرنامج الأصلي مع حسابات الفاصلة العائمة{ph1}. قبل أن يتمكن الوكيل من " +"اختبار تصحيح مفيد، كان عليه أن يحدد ما يجب قياسه." + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "" +"ويشير هذا إلى دور آخر لنموذج قادر على نطاق واسع: المساعدة في جعل المشكلة " +"قابلة للتحقق في المقام الأول. بمجرد وجود هذا الفحص، يمكننا التحقيق في المدى " +"الذي يمكن أن تصل إليه سياسة البحث المستفادة." + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "عندما يكون أداة التحقق خاطئًا" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"عندما نستخدم فحصًا في التدريب، يصبح نطاقه جزءًا من بيئة التعلم. أسمي هذا " +"المرجع أو أداة التحقق oracle. حتى الإجابة القابلة للتكرار يجب فهمها في حدود " +"ما تتحقق منه فعلًا." + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"أظهر TH08 مقدار ما يمكن إخفاءه خارج تلك التغطية. اجتازت بعض الوظائف المعاد " +"بناؤها مقارناتها الدقيقة مع ثوابت عائمة خاطئة. قامت أداة المقارنة بتعديل " +"العناوين المنقولة قبل التحقق من التعليمات، ولكنها لم تتحقق من القيم الموجودة" +" خلف تلك العناوين إلا عندما تم تسجيلها بشكل صريح للتحقق منها. يمكن أن تمر " +"المراجع الحرفية الأخرى دون فحص قيمها." + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"لسد هذه الفجوة، كشف {ph0}تدقيق أوسع{ph1} ثوابت خاطئة في دوال كانت قد اجتازت " +"التحقق. في إحدى العمليات الحسابية، أضافت الشيفرة المعاد بناؤها {ph2}، بينما " +"أضاف الأصل {ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}يمكن للنموذج الذي تمت مكافأته بفحص التحقق القديم أن يتعلم إنتاج إعادة " +"بناء غير صحيحة.{ph1} لم نقوم بتدريب نموذج RL باستخدام هذا المدقق. الفشل الذي" +" لاحظناه كان في الفحص نفسه. ولكن إذا استخدمناها كمكافأة، فإن نفس النقطة " +"العمياء ستصبح جزءًا من بيئة التعلم." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"يمكن أن يحتوي الاختبار الوظيفي على نقطة عمياء مماثلة. {ph0}وجدت الأبحاث التي" +" تستخدم التشويش التفاضلي في برامج فك التشفير LLM{ph1} وجود اختلافات سلوكية " +"خارج الاختبارات المتوفرة. لذلك نحن بحاجة إلى فهم اختبار النجاح من حيث " +"الحالات التي يمارسها. وبالمثل، يجب فهم مطابقة التعليمات من حيث البايتات " +"والبيانات التي تتحقق منها." + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"قبل استخدام أي نوع من اختبارات التحقق كمكافأة، سأختبره بنتائج غير صحيحة " +"عمدًا. أود أيضًا أن أبقي القبول النهائي منفصلاً عن كود المصدر الذي يمكن " +"لعامل الذكاء الاصطناعي تحريره. يجب أن يجتاز النموذج التحقق من خلال إعادة " +"بناء البرنامج بشكل صحيح. وبخلاف ذلك، فإن مجرد نسخ مصفوفة بايت من الهدف يمكن " +"أن يخدع نظام تسجيل ساذج دون استعادة كود المصدر المفيد." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "" +"{ph0}إن تحسين المتعلم وتحسين أداة التحقق من الصحة ينتميان إلى نفس مشكلة " +"البحث.{ph1} ومع تحسن المتعلم في تحسين التعليقات التي نقدمها له، يصبح فهم هذه" +" التعليقات أكثر أهمية أيضًا." + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "مقارنة تستحق التشغيل" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"مع إجراء عمليات التحقق هذه، سأبدأ المقارنة على مجموعة مهام VC7.1 ثابتة. " +"أولاً، أود أن أضع خطوط أساس لنموذج قوي للذكاء الاصطناعي للأغراض العامة " +"ونموذج أصغر. إن إضافة معرفة المستودع إلى النموذج الأصغر سيُظهر تغييرات " +"الاسترجاع. ومن هنا، فإن التخصص الخاضع للإشراف والنسخة المدربة RL ستسمح لنا " +"بفحص ما يضيفه التدريب." + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"ولجعل هذه المقارنات مفيدة، سيحصل كل نموذج على نفس الأدلة والأدوات المستهدفة." +" بالنسبة للمقارنات الخاصة بالتدريب، سأبقي النموذج الأساسي والمعرفة المتاحة " +"ثابتة أيضًا. من شأن التجارب المتكررة أن تساعد في التمييز بين استراتيجية " +"البحث الموثوقة والحل المرشح الذي ينجح بالصدفة." + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"سأفصل بعد ذلك شرطين للبدء: إعادة بناء دالة من تعليماتها، وإغلاق الاختلافات " +"القليلة الأخيرة في المصدر المحفوظ. قد يكون نموذج الذكاء الاصطناعي المتخصص " +"ممتازًا في المهمة الثانية، بينما يقوم نموذج الذكاء الاصطناعي للأغراض العامة " +"بالكثير من العمل اللازم للوصول إليه. وقياسها بشكل منفصل من شأنه أن يكشف عن " +"تقسيم العمل هذا." + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"تحتاج كلتا المهمتين إلى أمثلة اختبارية مستثناة من التدريب والاسترجاع. ألعاب " +"Touhou ذات الصلة تشترك في رمز المحرك. قد يؤدي استبعاد لعبة واحدة من التدريب " +"إلى ترك وظائف متطابقة تقريبًا في مجموعة التدريب. بدلاً من ذلك، سأستبعد " +"مجموعات كاملة من أكواد المصدر ذات الصلة وأحتفظ بإجاباتها التي تم التحقق منها" +" خارج كل من بيانات التدريب ومكتبة الاسترجاع." + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"بالنسبة لهذه الأمثلة، ستكون النتيجة تطابقات كاملة تم التحقق منها بشكل مستقل." +" من شأن الميزانيات المتساوية لمقترحات المرشحين أو محاولات التجميع أن تساعد " +"في مقارنة جودة البحث. إن قياس إجمالي الوقت والتكلفة، بما في ذلك التجميع، " +"سيُظهر ما إذا كانت هذه الجودة تنتج سير عمل فعالاً. وينبغي قياس تكاليف " +"التدريب بشكل منفصل." + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"كلا القياسين مهمان. يمكن أن يؤدي الاقتراح الرخيص إلى سير عمل مكلف إذا تسبب " +"في المزيد من التجميعات التي لا تقدم معلومات مفيدة. وعلى العكس من ذلك، قد " +"يكون النموذج الأبطأ أكثر اقتصادا إذا وجد تجربة مفيدة في وقت أقرب. وينبغي أن " +"تشمل المقارنة هذه التكاليف." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"كما أن حساب النتائج المقبولة يحافظ على التقدم المتوسط في المنظور الصحيح. بدا" +" أحد مرشحات TH09 {ph0}replay-save{ph1} واعدًا لأن الدالة المترجمة لها الحجم " +"المتوقع، ولكن المقارنة الكاملة لا تزال تجد اختلافات جوهرية. إن التغييرات في " +"كيفية قيام المترجم بترتيب التعليمات يمكن أن تجعل المرشح يبدو أقرب دون حل " +"المشكلة الأساسية. يمكن لمثل هذه التشخيصات أن توجه التجربة التالية، لكنني " +"سأؤكد صحة أي مكافأة مقابل \"الاقتراب\" مقابل فحص القبول الكامل." + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"سأكون مهتمًا بالنمط عبر هذه النتائج. إذا كان نموذج الذكاء الاصطناعي المتخصص " +"يعمل بشكل جيد ضمن عائلة المترجمات المألوفة، فهل ستصمد هذه الميزة بعد تغيير " +"سلسلة الأدوات؟ وبمجرد أن يتمتع كلا نموذجي الذكاء الاصطناعي بقدرة جيدة على " +"الاسترجاع، ما مقدار التدريب الذي سيضيفه؟ ستساعدنا الإجابات في تحديد المكان " +"الذي يكون فيه كل نوع من النماذج أكثر فائدة." + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "ما هو نوع وكيل الذكاء الاصطناعي الذي يشير إليه هذا؟" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"إذا تبين أن النماذج تساعد في مراحل مختلفة، فقد يكون الترتيب المفيد هو وكيل " +"واسع النطاق لديه إمكانية الوصول إلى نموذج متخصص للذكاء الاصطناعي. بمجرد أن " +"تصبح المهمة عبارة عن بحث مألوف للمترجم، يمكن أن تطلب نموذج الذكاء الاصطناعي " +"المتخصص للمرشحين. إذا لم تعد النتائج منطقية، فيمكن للعامل الأوسع العودة إلى " +"الدليل المستهدف أو التحقيق في القياس نفسه." + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "" +"وفي هذا الترتيب، يصبح التخصص أداة يمكن للعميل اختيارها مع تطور التحقيق. " +"يحتفظ الوكيل بحرية تغيير الاتجاه الذي جعل الاختراقات السابقة ممكنة." + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"ويأتي هذا بشكل طبيعي من التحول الصناعي الذي وصفته في المقالة السابقة. إن " +"القدرة على إجراء المزيد من التجارب تغير الطريقة التي ننظم بها العمل. كما أنه" +" يمنحنا سببًا للتساؤل عن القرارات التي تحتاج إلى حكم واسع النطاق وتلك التي " +"تتحسن من خلال الخبرة المتكررة في حرفة معينة." + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"حتى الآن، استحق أقوى نموذج عام مكانه في سير عملي لأنه حل مشكلات كنت قد " +"تركتها دون حل. وهذه النجاحات تدفعني إلى دراسة العملية: كم منها اعتمد على " +"اتساع قدراته، وكم يمكن أن يتولاه نموذج مدرب على هذا النوع من إعادة البناء؟" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "" +"{ph0}توفر لنا المستودعات طريقة لاختبار السؤال.{ph1} أود استخدام هذا السجل " +"لإجراء المقارنة ومعرفة ما نتعلمه." + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "الأدلة وإسناد النموذج" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"تصف الأمثلة المقارنات التاريخية على مستوى الوظيفة المسجلة في الالتزامات " +"المرتبطة. تعتبر عمليات التحقق من وقت تشغيل اللعبة بأكملها بمثابة مراحل " +"منفصلة. تمت مراجعة سجلات المصدر والمطابقة في 13 أكتوبر 2026." + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"التسمية TH09 {ph0} تعني GPT-6-Astra. تغير النموذج المرتبط بـ {ph1} بمرور " +"الوقت، لذا لا يمكن لهذه التسمية وحدها تحديد النموذج المستخدم في عملية تشغيل " +"معينة. توفر أسماء النماذج الصريحة في الكوميتات المذكورة الأخرى الإسناد " +"المسجل. لا تتضمن هذه السجلات قياسات متسقة للتكلفة أو الجهد لكل عملية تشغيل." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "" +"{ph0}TH09 عمر الكائن المؤقت:{ph1} تم التحقق من {ph2}مراجعة السياق " +"السابقة{ph3} و{ph4}إعادة البناء الكاملة من خلال إعادة تجميع نظيفة من " +"المصدر{ph5}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"{ph0}TH09 Front رد الاتصال:{ph1} {ph2}مناطق التشخيص التي لم تتطابق مع{ph3}، " +"والرسم البياني الجديد لتدفق التحكم في {ph4}Astra{ph5} و{ph6}فحص إعادة " +"الترجمة المقبول{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}معرفة المترجم:{ph1} {ph2}TH095 إعادة استخدام سلوك مجموعة المعرفات{ph3}،" +" {ph4}TH04 شيفرة اللاعب وترتيب الرابط{ph5} و{ph6}Luna إعادة البناء الكاملة " +"لوظيفة إنشاء العدو لـ TH09{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}عمليات الفحص والتشخيص:{ph1} {ph2}TH08 التدقيق الثابت للفاصلة " +"العائمة{ph3}، و{ph4}TH08 التحقيق الرقمي{ph5} و{ph6}TH09 إعادة البناء مع " +"توفير إعادة التشغيل{ph7}." + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "" +"المقارنات المقترحة للنماذج المتخصصة والتدريب RL هي تجارب مستقبلية. تاريخ " +"المشروع يحفزهم. لم يتم تقييم أي نموذج متخصص مدرب لهذا المقال." + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "هل تحتاج الهندسة العكسية إلى نموذج أكبر؟ | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "" +"ما تعلمته من إعادة بناء Touhou عن النماذج العامة والمتخصصة، وعن تعلم اقتراح " +"فرضيات أفضل من ملاحظات المترجم البرمجي." + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "في هذه الصفحة" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "النماذج والهندسة العكسية مقال" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "تجارب إعادة بناء الشيفرة المختارة" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "العودة للأعلى" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "" +"تتضمن {ph0}ملاحظات الأدلة التفصيلية{ph1} المقارنات المسجلة وسياق التجارب." + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "بقلم N0zoM1z0 · 13 أكتوبر 2026 · مسودة للمراجعة" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "دليل الإعداد" diff --git a/website/locales/de/messages.po b/website/locales/de/messages.po index ee3fec463..2b23bc4a3 100644 --- a/website/locales/de/messages.po +++ b/website/locales/de/messages.po @@ -32,18 +32,18 @@ msgid "Thoughts on reverse engineering." msgstr "Gedanken zum Reverse Engineering." #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "Spielrekonstruktion{ph0}Essay" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "Die industrielle Revolution im Reverse Engineering" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " @@ -53,19 +53,20 @@ msgstr "" "gelehrt, über Agenten, Überprüfung und Wissen, dass Verbindungen über " "Projekte hinweg." -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "Lesen Sie den Artikel" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "Von N0zoM1z0 · 10. Oktober 2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -101,6 +102,8 @@ msgstr "" "REA und KI-Agenten." #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -137,6 +140,7 @@ msgstr "" "Ihrem Codierungsagenten." #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -157,6 +161,7 @@ msgid "REA home" msgstr "REA-Startseite" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -177,6 +182,7 @@ msgid "Main navigation" msgstr "Hauptnavigation" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -197,6 +203,7 @@ msgid "REA on GitHub" msgstr "REA auf GitHub" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -217,6 +224,7 @@ msgid "Join REA on Discord" msgstr "REA auf Discord beitreten" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -236,7 +244,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "REA auf X folgen" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "Nach oben" @@ -11845,6 +11853,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "Gleicher Abstand: 256 ÷ 16 = 16 Winkeleinheiten = 22,5°" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -11865,6 +11874,7 @@ msgid "Showcases" msgstr "Fallstudien" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -11885,6 +11895,7 @@ msgid "Blog" msgstr "Blog" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -11905,6 +11916,7 @@ msgid "Get started" msgstr "Erste Schritte" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -11924,7 +11936,8 @@ msgctxt "shared" msgid "Guides" msgstr "Anleitungen" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -11944,7 +11957,8 @@ msgctxt "shared" msgid "Source" msgstr "Quellcode" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -11964,7 +11978,8 @@ msgctxt "shared" msgid "MIT license" msgstr "MIT-Lizenz" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -11984,7 +11999,8 @@ msgctxt "shared" msgid "Join the community" msgstr "Zur Community" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -12957,6 +12973,1412 @@ msgstr "" "oder verbinden Sie den MCP-Server von Everywhere, um aufgezeichneten " "Datenverkehr mit Ihrem Agenten zu untersuchen." +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "Spezialisierte Modelle{ph0}Essay" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "Braucht Reverse Engineering ein größeres Modell?" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "" +"Was die Rekonstruktion von Touhou über allgemeine und spezialisierte Modelle" +" sowie das Lernen aus Compiler-Rückmeldungen zeigt." + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Von N0zoM1z0 · 13. Oktober 2026" + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "Zum Inhalt springen" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "{ph0}Home{ph1} / {ph2}Blog{ph3} / Modelle und Reverse Engineering" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "Aufsatz" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "Braucht Reverse Engineering ein größeres Modell?" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Von N0zoM1z0 · 13. Oktober 2026" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "Das Wichtigste" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "" +"{ph0}Die Modellfähigkeit beeinflusst, welche Hypothesen ein KI-Agent " +"vorschlagen kann.{ph1} Spätere Sitzungen lösten Probleme, die in früheren " +"Arbeiten ungelöst geblieben waren." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "" +"{ph0}Ein bekannter Compiler bietet konkrete Muster für ein spezielles Modell" +" zum Lernen.{ph1} Einige genaue Maschinencode-Übereinstimmungen hängen von " +"bestimmten, wiederverwendbaren Quellcodemustern ab." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "" +"{ph0}Beziehen Sie das Repository-Wissen in einen fairen Vergleich ein.{ph1} " +"Ein kleineres Modell mit gutem Wissensabruf verfügt möglicherweise bereits " +"über genügend Informationen, um Fortschritte zu erzielen." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "" +"{ph0}Trainieren Sie das Modell, um das nächste nützliche Experiment " +"auszuwählen, und testen Sie seinen Prüfer.{ph1} Feedback ist nur insoweit " +"nützlich, als der Prüfer die richtigen Dinge überprüft." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "" +"{ph0}Bewerten Sie verifizierte Rekonstruktionsergebnisse neben Zeit und " +"Kosten.{ph1} Das ist es, was ich für den gesamten KI-Agent-Workflow messen " +"möchte." + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "In diesem Artikel" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}Was leistungsfähigere Modelle verändert haben{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}Warum spezialisieren?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}Wo sollte diese Erfahrung gespeichert werden?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}Lernen Sie das nächste nützliche Experiment{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}Reverse Engineering und verstärkendes Lernen{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}Wenn der Prüfer falsch ist{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}Ein Vergleich, der sich lohnt{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}Was für einen KI-Agenten lässt dies vermuten?{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "Was leistungsfähigere Modelle verändert haben" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"Seit August 2026 erforsche ich, wie viel Reverse Engineering ein Agent mit " +"Zugriff auf ein Programm und einer Möglichkeit zur Überprüfung seiner Arbeit" +" durchführen kann. Der größte Teil meiner Erfahrung stammt aus der " +"Rekonstruktion von Spielen, insbesondere Touhou. Da ich die Modelle geändert" +" habe, haben die Repositorys aufgezeichnet, was jede Sitzung " +"wiederherstellen konnte." + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"Ein Großteil dieser Arbeit zielt auf eine exakte Rekonstruktion ab: Wir " +"kompilieren die gepflegte Quelle unter einer historischen Toolchain mit " +"festen Versionen und prüfen, ob sie die Zielfunktion reproduziert. Wenn ein " +"späteres Modell erfolgreich ist, wo frühere Arbeiten ins Stocken geraten " +"sind, zeigen die Quelländerungen, was diesen Fortschritt ermöglicht hat." + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "Die temporären Variablen benötigten überlappende Lebensdauern" + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"Ein Großteil der Logik einer TH09-Angriffsfunktion war bereits " +"rekonstruiert, aber der Compiler speicherte temporäre Ergebnisse immer noch " +"anders als das Original. Das verbleibende Problem bestand darin, wie lange " +"diese Ergebnisse am Leben bleiben mussten und wann ihr Speicher " +"wiederverwendet werden konnte." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"Ein {ph0}GPT-6-Sol-Sitzungsdatensatz{ph1} hat diese Nichtübereinstimmung " +"gemeldet, nachdem mehrere gewöhnliche Quellcode-Anordnungen getestet wurden." +" Als {ph2}GPT-6.1-Sol das Problem erneut untersuchte{ph3}, schlug es eine " +"nützliche Hypothese über die Lebensdauer dieser temporären Variablen vor." + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"Die Funktion erzeugte temporäre Ergebnisse und kopierte sie in " +"Animationspositionen. In C++ bleibt ein temporäres Ergebnis bestehen, bis " +"der Ausdruck, der es verwendet, beendet ist. Durch die Gruppierung der " +"realen Operationen in einem Ausdruck blieben diese Ergebnisse zusammen " +"erhalten, sodass der Compiler nicht mehr denselben Speicher für alle " +"wiederverwenden konnte." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"Ein Ergebnis wird weiterhin gemeinsam mit einem Wert gespeichert, der später" +" für Kollisionsprüfungen verwendet wird. Indem man diesem Wert seine eigene " +"Lebensdauer zuordnete, wurde die verbleibende Überlappung behoben. Nach " +"mehreren gezielten Experimenten bestätigte {ph0}eine saubere Neukompilierung" +" aus dem Quellcode, dass die vollständige Funktion übereinstimmte{ph1}." + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"Mich interessiert, wie sich Entdeckung und Tests gegenseitig unterstützten. " +"Die Hypothese über die temporäre Lebensdauer von Objekten gab dem KI-Agenten" +" eine neue Richtung. Das Feedback des Compilers half dabei, diese Hypothese " +"in eine passende Quellcode-Anordnung zu verfeinern." + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "Ein anderes Kontrollflussdiagramm" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"Eine zweite TH09-Funktion zeigt, warum eine neue Richtung wichtig sein kann." +" Hier ging es darum, wie mehrere Verzweigungen dieselben abschließenden " +"Operationen nutzen. {ph0}GPT-6.1-Sols frühere Arbeit{ph1} brachte Teile der " +"Funktion zur Übereinstimmung, doch die Verzweigungen liefen noch anders " +"zusammen als im Original." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}GPT-6-Astra hat das umgebende Kontrollflussdiagramm{ph1} geändert. Die " +"Hauptwege führten nun zu einer gemeinsamen finalen Aktualisierung und " +"Rückkehr. In dieser Quellstruktur kombinierte der Compiler die Zweige auf " +"die gleiche Weise wie im Original. Die vollständige Funktion stimmte überein" +" und eine {ph2}separate Neuerstellungsprüfung bestätigte dies{ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}Durch die Änderung der Darstellung wurde ein produktiverer Suchraum " +"eröffnet.{ph1} Beide Fälle geben mir einen Grund, die allgemeine " +"Modellfähigkeit ernst zu nehmen: Ein Agent kann lange Zeit lokale " +"Variationen ausprobieren, bevor er eine bessere Möglichkeit findet, die " +"umgebende Arbeit auszudrücken." + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"Die späteren Sitzungen übernahmen allerdings auch früheren Quellcode und " +"aufgezeichnete Fehlversuche. Diese Vorarbeit war Teil ihres Vorteils. Die " +"Historie macht die Entdeckungen und ihre Prüfungen nachvollziehbar. Ein " +"kontrollierter Vergleich würde helfen, den Beitrag des Modells vom Beitrag " +"der übernommenen Erfahrung zu trennen." + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"Das macht die Frage für mich interessant. Einige Fortschritte wurden durch " +"die Suche nach einer neuen Vertretung erzielt. Ein Großteil der " +"verbleibenden Arbeit bestand darin, verschiedene Quellcode-Anordnungen mit " +"einem vertrauten Compiler zu testen. Wie viel davon erfordert ein breites " +"Denkvermögen? Wie viel könnte ein Modell lernen, wenn es wiederholt mit " +"diesem Compiler und Code arbeitet?" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "Warum könnte ein spezialisiertes KI-Modell gut funktionieren?" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"Touhou gibt uns einen konkreten Grund zu der Annahme, dass diese Erfahrung " +"hilfreich sein wird. Ein Großteil des Spielcodes stammt vom selben Autor, " +"ZUN, daher sind wiederkehrende Gewohnheiten eine vernünftige " +"Ausgangsannahme. Die Repositories untermauern dies mit nützlichen " +"Beispielen: Verwandte Schleifen und Hilfsanordnungen haben spielübergreifend" +" Hypothesen geliefert." + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "" +"Diese Quellmuster werden spezifischer, wenn wir den Compiler einbeziehen. " +"Unter einer bestimmten Version und einem bestimmten Optionssatz können " +"kleine Änderungen in der Quelle zu wiederholbaren Unterschieden im " +"Maschinencode führen. Einige dieser Unterschiede sind überraschend unklar." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"In TH095 beispielsweise könnte {ph0}sogar der Name einer lokalen Variablen " +"Einfluss darauf haben, wo VC7.1 sie gespeichert hat{ph1}. Das Verschieben " +"der Deklaration hat das Speicherlayout nicht gelöst. Allerdings hatte eine " +"frühere Hintergrundfunktion ein Namensmuster offenbart, das die Wahl des " +"Compilers beeinflusste. Das legte eine vielversprechendere Hypothese für die" +" {ph2}Rekonstruktion von {ph3}{ph4} nahe." + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "" +"Durch die Wiederverwendung dieses Musters für die Dateigrößenvariable wurde " +"das erforderliche Layout erstellt, ohne dass Speicherplatz hinzugefügt " +"werden musste. Die gesamte Funktion stimmte dann überein." + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "" +"Dies ist ein sehr spezifisches Detail, das einem allgemeines KI-Modell " +"möglicherweise nicht bekannt ist, wenn es zum ersten Mal auf das Problem " +"stößt. Ein auf diesen Compiler spezialisiertes Modell könnte viele solcher " +"Fälle erkennen und herausfinden, welche Quellcodevarianten es wert sind, " +"zuerst getestet zu werden." + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"Die Chance wird besonders deutlich bei finalen Matching-Problemen, bei denen" +" wir das Verhalten bereits verstehen. Wir fragen uns dann, welche " +"gewöhnliche Quellcodeanordnung dieser Compiler in die beobachteten " +"Anweisungen umwandelt. Durch die Spezialisierung könnte das Modell diese " +"Formen effizienter vorschlagen, während das Ziel weiterhin bestimmt, welche " +"Hypothesen bestehen bleiben." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"Nützliche Muster müssen ihren Kontext behalten. TH08 verwendet eine frühere " +"Visual C++-Version als TH095 und TH09. TH04 verwendet einen anderen Compiler" +" aus der DOS-Ära. Für die {ph0}Rekonstruktion des Spielercodes{ph1} waren " +"unterschiedliche Hypothesen über Quellcodemuster und die Art und Weise " +"erforderlich, wie kompilierter Code mit einer ausführbaren Datei verknüpft " +"wurde. Wenn wir denselben Autor haben, haben wir zunächst eine Erwartung, " +"aber jedes Ziel sagt uns, ob es zutrifft. Ein spezielles Modell müsste diese" +" Kontexte unterscheiden." + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "Wo sollte diese Erfahrung gespeichert werden?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"Bevor ich mich entscheide, diese Muster durch Modelltraining zu lehren, " +"würde ich mir das Wissen ansehen, das wir bereits im Repository speichern. " +"Im {ph0}vorherigen Aufsatz{ph1} habe ich darüber geschrieben, dass es zum " +"Arbeitsgedächtnis des Projekts wird. Dieser Speicher umfasst Compiler-" +"Lektionen sowie die Quelle und fehlgeschlagene Experimente, die sie nützlich" +" gemacht haben." + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"Durch das Abrufen dieses Datensatzes kann ein Agent mit einem bekannten " +"Ergebnis beginnen und prüfen, wie wir zu diesem Ergebnis gelangt sind. Es " +"können auch Alternativen vermieden werden, die im gleichen Kontext bereits " +"gescheitert sind. Der Ausgangspunkt verbessert sich, ohne die trainierten " +"Parameter des Modells zu ändern." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"Bei der Rekonstruktion der Funktion von TH09 zum Erstellen von Feinden hat " +"eine {ph0}GPT-6-Luna-max-Sitzung{ph1} eine Hypothese aus dem zugehörigen " +"TH08-Quellcode übernommen. Dieser frühere Code schlug vor, wie die Schleife " +"organisiert und Fehler darin behandelt werden sollten. Die eigenen Beweise " +"von TH09 lieferten die spielspezifischen Details. Neuaufbauten aus der " +"Quelle bestätigten, dass die vollständige Funktion übereinstimmte." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}„Das Modell kannte diese Compiler-Eigenart nicht“ und „Das Modell " +"konnte sie nicht verwenden“ sind unterschiedliche Probleme.{ph1} Das erste " +"Problem kann durch das Abrufen gelöst werden, aber die Umwandlung dieser " +"Tatsache in einen nützlichen Kandidaten erfordert noch Arbeit. Und wenn der " +"Quellcode des Kandidaten fehlschlägt, muss das Modell entscheiden, was das " +"Ergebnis für seinen nächsten Versuch bedeutet. Die Kenntnis des relevanten " +"Musters ist nur der Anfang dieses Prozesses." + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"Aus diesem Grund würde ich in jeden Vergleich ein kleineres allgemeines KI-" +"Modell mit gutem Abruf einbeziehen. Wenn wir ihm die gleiche " +"Erfahrungsbibliothek zur Verfügung stellen, können wir herausfinden, was die" +" Schulung bringt: bessere Kandidatengenerierung, bessere Entscheidungen nach" +" Feedback oder beides." + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "Lernen Sie das nächste nützliche Experiment" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"Diese Entscheidungen nach Feedback sind das, was ich am liebsten studieren " +"würde. Bei der Agentenrekonstruktion schlägt das Modell eine Erklärung vor " +"und testet sie anhand des Programms. Selbst wenn der Quellcode des " +"Kandidaten fehlschlägt, kann das Ergebnis die verbleibenden Möglichkeiten " +"einschränken und ein nützlicheres nächstes Experiment vorschlagen." + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "" +"Das Beispiel der temporären Ergebnisse zeigt auch das. Der endgültige " +"Quellcode enthält die Anordnung, die funktioniert hat. Der Weg dorthin " +"enthält jedoch zusätzliche Informationen: Jedes der folgenden Experimente " +"zeigte, was noch geändert werden musste." + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "Experimentieren" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "Was uns das Ergebnis lehrte" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "" +"Versuchen Sie es mit einer anderen Möglichkeit, die Ergebnisse zu kopieren" + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "" +"Der Kopiercode ändert sich, aber die Funktion unterscheidet sich immer noch." + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "Verwenden Sie die zurückgegebenen Werte direkt" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "" +"Das Kopieren erfolgt nach dem ursprünglichen Muster, die temporäre " +"Speicherung unterscheidet sich jedoch noch." + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "Halten Sie alle temporären Variablen gleichzeitig gültig" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "" +"Sie erhalten einen separaten Speicher, aber einer überlappt immer noch einen" +" Wert, der später für Kollisionsprüfungen verwendet wird." + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "Halten Sie den Wert für die Kollisionsprüfung getrennt" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "" +"Eine saubere Neukompilierung aus dem Quellcode bestätigt die vollständige " +"Übereinstimmung." + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "" +"Ausgewählte Experimente aus der Angriffsfunktionsrekonstruktion oben, " +"gruppiert nach dem, was sie uns gelehrt haben." + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"Eine Trainingsaufzeichnung, die diese Reihenfolge beibehält, kann mehr " +"lehren als die endgültige Quelle allein. Es verbindet jede vorgeschlagene " +"Änderung mit einem beobachteten Ergebnis und der nächsten Entscheidung. Es " +"ist auch wichtig, ineffektive Variationen beizubehalten: Sie teilen einem " +"späteren Agenten mit, welche Hypothesen in diesem Zusammenhang bereits " +"getestet wurden." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}Ich möchte, dass das Modell lernt, Feedback zu nutzen.{ph1} Ein " +"neutrales Ergebnis ist ein Grund, die Variation noch einmal zu überdenken. " +"Eine veränderte Nichtübereinstimmung kann auf eine andere Ursache hinweisen." +" Wenn lokale Änderungen nicht mehr informativ sind, sollte der Agent in der " +"Lage sein, die Quellendarstellung noch einmal aufzurufen oder die Beweise " +"erneut zu prüfen." + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"Zu lernen, diese Entscheidungen zu treffen, erfordert Autonomie. Manchmal " +"besteht der nützliche nächste Schritt darin, einen anderen Aufrufer zu " +"überprüfen, anstatt eine weitere Bearbeitung zu kompilieren. Eine starre " +"Abfolge erforderlicher Umschreibungen würde diese Wahlmöglichkeit zusammen " +"mit einem Teil des Verhaltens, das das Modell lernen soll, aufheben." + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "Warum Reverse Engineering für Reinforcement Learning interessant ist" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"Rekonstruktion mit klar abgegrenztem Umfang bietet eine praktische Umgebung," +" um diese Entscheidungen zu untersuchen. Bei festgelegtem Ziel und Compiler " +"liefern viele Quellcodeexperimente schnelles, wiederholbares Feedback. Der " +"Agent kann einen Kandidaten kompilieren, die Abweichungen prüfen und daraus " +"den nächsten Schritt wählen." + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"Reinforcement Learning könnte diesen Entscheidungsprozess durch das " +"erhaltene Feedback trainieren. Ein durch eine definierte Prüfung " +"angenommener Kandidat gibt uns ein konkretes Ergebnis, während wir anhand " +"der Abfolge der Versuche sehen können, wie viel Arbeit es gekostet hat, " +"dieses zu erreichen." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"Es gibt bereits Forschungsergebnisse, die diese Richtung unterstützen. " +"{ph0}LLM4Decompile{ph1} untersucht Modelle, die auf die Dekompilierung " +"spezialisiert sind. {ph2}AutoDecompiler{ph3} trainiert die Multi-Turn-" +"Verfeinerung mithilfe von Compiler- und Ausführungsfeedback. Der Schwerpunkt" +" ihrer Studien liegt auf der Wiederherstellung des Programmverhaltens. Für " +"diese Arbeit würde ich sie als Ausgangspunkt für die damit verbundene " +"Aufgabe verwenden, eine Quelle zu finden, die mit der Ausgabe eines " +"historischen Compilers übereinstimmt." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"Um eine so klar definierte Aufgabe zu erfüllen, müssen wir jedoch " +"möglicherweise zunächst feststellen, welche Ressourcen eine Funktion " +"besitzt, oder eine neue Methode zur Beobachtung des Programms während der " +"Ausführung entwickeln. In TH08 beispielsweise führte ein " +"{ph0}Kollisionsunterschied dazu, wie das ursprüngliche Programm " +"Gleitkommaberechnungen verarbeitete{ph1}. Bevor der Agent eine nützliche " +"Korrektur testen konnte, musste er herausfinden, was gemessen werden sollte." + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "" +"Dies deutet auf eine weitere Rolle eines allgemein leistungsfähigen Modells " +"hin: Es hilft dabei, das Problem überhaupt überprüfbar zu machen. Sobald " +"diese Prüfung vorliegt, können wir untersuchen, wie weit eine erlernte " +"Suchrichtlinie damit kommen kann." + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "Wenn der Prüfer falsch ist" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"Wenn wir eine Prüfung für das Training verwenden, wird auch ihr " +"Prüfungsumfang Teil der Lernumgebung. Ich nenne eine solche Referenz oder " +"einen solchen Prüfer ein Oracle. Selbst eine wiederholbare Antwort müssen " +"wir danach beurteilen, was sie tatsächlich überprüft." + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"TH08 hat gezeigt, wie viel sich außerhalb dieser Abdeckung verbergen kann. " +"Einige rekonstruierte Funktionen haben ihre exakten Vergleiche mit falschen " +"Gleitkommakonstanten bestanden. Der Komparator passte die verschobenen " +"Adressen an, bevor er die Anweisungen überprüfte, überprüfte die Werte " +"hinter diesen Adressen jedoch nur, wenn sie explizit zur Überprüfung " +"aufgezeichnet wurden. Andere wörtliche Verweise könnten ohne Prüfung ihrer " +"Werte bestehen bleiben." + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"Um diese Lücke zu schließen, wurden bei einer {ph0}umfassenderen " +"Prüfung{ph1} falsche Konstanten in Funktionen gefunden, die bereits die " +"Überprüfung bestanden hatten. In einer Berechnung fügte der rekonstruierte " +"Quellcode {ph2} hinzu, während das Original {ph3} hinzufügte." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}Ein Modell, das durch die alte Verifizierungsprüfung belohnt wurde, " +"könnte lernen, eine falsche Rekonstruktion zu erzeugen.{ph1} Wir haben mit " +"diesem Prüfer kein RL-Modell trainiert. Der von uns beobachtete Fehler lag " +"in der Prüfung selbst. Aber wenn wir es als Belohnung nutzen würden, würde " +"derselbe blinde Fleck Teil der Lernumgebung werden." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"Ein Funktionstest kann einen ähnlichen blinden Fleck haben. " +"{ph0}Untersuchungen mit differenziellem Fuzzing auf LLM-Decompilern{ph1} " +"ergaben Verhaltensunterschiede außerhalb der bereitgestellten Tests. Wir " +"müssen daher einen bestandenen Test im Hinblick auf die Fälle verstehen, in " +"denen er durchgeführt wird. Ebenso muss eine Befehlsübereinstimmung im " +"Hinblick auf die Bytes und Daten verstanden werden, die sie überprüft." + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"Bevor ich eine Art Verifizierungsprüfung als Belohnung verwende, würde ich " +"sie mit absichtlich falschen Ergebnissen testen. Ich würde die Endabnahme " +"auch getrennt vom Quellcode durchführen, den der KI-Agent bearbeiten kann. " +"Das Modell muss die Verifizierung bestehen, indem es das Programm korrekt " +"rekonstruiert. Andernfalls könnte das einfache Kopieren eines Byte-Arrays " +"vom Ziel ein naives Bewertungssystem täuschen, ohne dass nützlicher " +"Quellcode wiederhergestellt wird." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "" +"{ph0}Die Verbesserung des Lernenden und die Verbesserung seines Prüfers " +"gehören zum selben Forschungsproblem.{ph1} Je besser der Lernende darin " +"wird, das Feedback, das wir ihm geben, zu optimieren, desto wichtiger wird " +"auch das Verständnis dieses Feedbacks." + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "Ein Vergleich, der sich lohnt" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"Wenn diese Prüfungen vorhanden sind, würde ich den Vergleich für eine feste " +"VC7.1-Aufgabenfamilie starten. Zunächst würde ich Grundlinien für ein " +"starkes allgemeines KI-Modell und ein kleineres Modell festlegen. Das " +"Hinzufügen von Repository-Wissen zum kleineren Modell würde zeigen, welche " +"Änderungen sich beim Abruf ergeben. Von dort aus würden wir durch eine " +"überwachte Spezialisierung und eine RL-trainierte Version untersuchen " +"können, was Training hinzufügt." + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"Um diese Vergleiche aussagekräftig zu machen, würde jedes Modell die " +"gleichen Zieldaten und Tools erhalten. Für die ausbildungsspezifischen " +"Vergleiche würde ich das Basismodell und das verfügbare Wissen ebenfalls " +"unverändert lassen. Wiederholte Versuche würden dabei helfen, eine " +"zuverlässige Suchstrategie von einer Kandidatenlösung zu unterscheiden, die " +"zufällig erfolgreich ist." + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"Ich würde dann zwei Startbedingungen trennen: die Rekonstruktion einer " +"Funktion aus ihren Anweisungen und die Beseitigung der letzten paar " +"Unterschiede in der gepflegten Quelle. Bei der zweiten Aufgabe könnte ein " +"spezialisiertes KI-Modell hervorragend geeignet sein, während ein " +"allgemeines KI-Modell einen Großteil der dafür erforderlichen Arbeit " +"übernimmt. Eine getrennte Messung würde diese Arbeitsteilung offenbaren." + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"Für beide Aufgaben sind Testbeispiele erforderlich, die vom Training und " +"Abruf ausgeschlossen sind. Verwandte Touhou-Spiele teilen den Engine-Code. " +"Der Ausschluss eines Spiels vom Training könnte dennoch dazu führen, dass " +"nahezu identische Funktionen im Trainingsset verbleiben. Stattdessen würde " +"ich ganze Gruppen verwandten Quellcodes ausschließen und ihre verifizierten " +"Antworten sowohl aus den Trainingsdaten als auch aus der Abrufbibliothek " +"heraushalten." + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"Das Ergebnis wären vollständige, unabhängig verifizierte Übereinstimmungen. " +"Gleiche Budgets für Kandidaten oder Kompilierungsversuche helfen, die " +"Suchqualität zu vergleichen. Gesamtzeit und Gesamtkosten einschließlich " +"Kompilierung zeigen, ob diese Qualität einen effizienten Arbeitsablauf " +"ermöglicht. Trainingskosten sollten separat erfasst werden." + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"Beide Messungen sind wichtig. Ein billiger Vorschlag kann zu einem teuren " +"Arbeitsablauf führen, wenn er mehr Kompilierungen verursacht, die keine " +"nützlichen Informationen liefern. Umgekehrt kann ein langsameres Modell " +"wirtschaftlicher sein, wenn es früher ein nützliches Experiment findet. Der " +"Vergleich sollte diese Kosten einbeziehen." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"Akzeptierte Ergebnisse zu zählen hilft auch, Zwischenfortschritte " +"einzuordnen. Ein {ph0}Replay-Save-Kandidat{ph1} aus TH09 wirkte " +"vielversprechend, weil die kompilierte Funktion die erwartete Größe hatte. " +"Der vollständige Vergleich fand aber noch erhebliche Unterschiede. Eine " +"andere Anordnung der Befehle kann einen Kandidaten näher am Ziel erscheinen " +"lassen, ohne das eigentliche Problem zu lösen. Solche Diagnosen können das " +"nächste Experiment leiten; eine Belohnung für mehr Nähe würde ich jedoch " +"anhand der vollständigen Abnahmeprüfung validieren." + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"Mich würde das Muster dieser Ergebnisse interessieren. Wenn ein " +"spezialisiertes KI-Modell in einer bekannten Compilerfamilie gut " +"funktioniert, überlebt dieser Vorteil dann auch eine Änderung der Toolchain?" +" Und wenn beide KI-Modelle eine gute Retrievalfähigkeit haben, wie viel " +"bringt das Training dann noch? Die Antworten würden uns helfen zu " +"entscheiden, wo welche Art von Modell am nützlichsten ist." + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "Was für einen KI-Agenten lässt dies vermuten?" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"Wenn sich herausstellt, dass die Modelle in verschiedenen Phasen hilfreich " +"sind, könnte ein umfassender Agent mit Zugriff auf ein spezielles KI-Modell " +"eine nützliche Lösung sein. Sobald eine Aufgabe zu einer vertrauten " +"Compiler-Suche wird, könnte sie das spezialisierte KI-Modell nach Kandidaten" +" fragen. Wenn die Ergebnisse keinen Sinn mehr ergeben, könnte der breitere " +"Agent zum Zielbeweis zurückkehren oder die Messung selbst untersuchen." + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "" +"In dieser Vereinbarung wird die Spezialisierung zu einem Instrument, das der" +" Agent im Verlauf der Untersuchung wählen kann. Der Agent behält die " +"Freiheit, die Richtung zu ändern, die die früheren Durchbrüche ermöglicht " +"hat." + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"Dies ergibt sich natürlich aus dem industriellen Wandel, den ich im " +"vorherigen Aufsatz beschrieben habe. Die Möglichkeit, viel mehr Experimente " +"durchführen zu können, verändert die Art und Weise, wie wir die Arbeit " +"organisieren. Es gibt uns auch einen Grund zu fragen, welche Entscheidungen " +"ein breites Urteilsvermögen erfordern und welche sich durch wiederholte " +"Erfahrung mit einem bestimmten Handwerk verbessern." + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"Vorerst hat sich das stärkste allgemeine KI-Modell seinen Platz in meinem " +"Arbeitsablauf verdient, indem es Probleme löste, die ich ungelöst gelassen " +"hatte. Gerade diese Erfolge machen mich neugierig: Wie viel hing von seiner " +"breiten Fähigkeit ab? Wie viel könnte ein Modell übernehmen, das auf diese " +"Art der Rekonstruktion spezialisiert ist?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "" +"{ph0}Die Repositorys bieten uns eine Möglichkeit, die Frage zu testen.{ph1} " +"Ich möchte diesen Datensatz verwenden, um den Vergleich zu erstellen und zu " +"sehen, was wir lernen." + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "Beweise und Modellzuschreibung" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"Die Beispiele beschreiben historische Vergleiche auf Funktionsebene, die in " +"den verknüpften Commits aufgezeichnet wurden. Laufzeitprüfungen für das " +"gesamte Spiel sind separate Meilensteine. Quelle und übereinstimmende " +"Aufzeichnungen wurden am 13. Oktober 2026 überprüft." + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"Die Bezeichnung TH09 {ph0} bedeutet GPT-6-Astra. Das mit {ph1} verknüpfte " +"Modell hat sich im Laufe der Zeit geändert, sodass die Bezeichnung allein " +"das in einem bestimmten Lauf verwendete Modell nicht identifizieren kann. " +"Explizite Modellnamen in den anderen zitierten Commits liefern die " +"aufgezeichnete Zuschreibung. Diese Historien enthalten keine konsistenten " +"Messungen der Kosten oder des Aufwands für jeden Lauf." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "" +"{ph0}TH09 temporäre Objektlebensdauern:{ph1} die {ph2}frühere " +"Kontextüberprüfung{ph3} und {ph4}vollständige Rekonstruktion, verifiziert " +"durch eine saubere Neukompilierung aus der Quelle{ph5}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"{ph0}TH09 Front-Callback:{ph1} {ph2}Diagnosebereiche, die nicht " +"übereinstimmten{ph3}, {ph4}Astras neues Kontrollflussdiagramm{ph5} und seine" +" {ph6}akzeptierte Neukompilierungsprüfung{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}Compiler-Kenntnisse:{ph1} {ph2}TH095 Wiederverwendung des Identifier-" +"Bucket-Verhaltens{ph3}, {ph4}TH04 Player-Quellcode und Linker-" +"Reihenfolge{ph5} und {ph6}Lunas vollständige Rekonstruktion der " +"Feinderschaffungsfunktion von TH09{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}Prüfungen und Diagnosen:{ph1} {ph2}TH08-Prüfung der " +"Gleitkommakonstanten{ph3}, {ph4}TH08-Untersuchung numerischer " +"Unterschiede{ph5} und {ph6}TH09-Rekonstruktion der Replay-Speicherung{ph7}." + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "" +"Die vorgeschlagenen Vergleiche spezialisierter Modelle und RL-Training sind " +"zukünftige Experimente. Die Projektgeschichten motivieren sie. Für diesen " +"Aufsatz wurde kein trainiertes Spezialmodell evaluiert." + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "Braucht Reverse Engineering ein größeres Modell? | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "" +"Was ich durch die Rekonstruktion von Touhou über allgemeine Modelle, " +"Spezialmodelle und das Lernen, bessere Hypothesen anhand des Compiler-" +"Feedbacks aufzustellen, gelernt habe." + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "Auf dieser Seite" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "Essay über Modelle und Reverse Engineering" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "Ausgewählte Rekonstruktionsexperimente" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "Nach oben" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "" +"Die {ph0}ausführlichen Evidenznotizen{ph1} enthalten die aufgezeichneten " +"Vergleiche und den Kontext der Experimente." + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "Von N0zoM1z0 · 13. Oktober 2026 · Entwurf zur Durchsicht" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "Einrichtungsanleitung" diff --git a/website/locales/es/messages.po b/website/locales/es/messages.po index f40b06204..bc68e0b74 100644 --- a/website/locales/es/messages.po +++ b/website/locales/es/messages.po @@ -32,18 +32,18 @@ msgid "Thoughts on reverse engineering." msgstr "Reflexiones sobre ingeniería inversa." #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "Reconstrucción del juego{ph0}Ensayo" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "La revolución industrial en ingeniería inversa" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " @@ -53,19 +53,20 @@ msgstr "" "enseñó sobre los agentes, la verificación y el conocimiento que componen los" " proyectos." -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "Leer el artículo" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "Por N0zoM1z0 * 10 octubre 2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -101,6 +102,8 @@ msgstr "" "con REA y agentes de IA." #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -137,6 +140,7 @@ msgstr "" "de codificación." #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -157,6 +161,7 @@ msgid "REA home" msgstr "Inicio de REA" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -177,6 +182,7 @@ msgid "Main navigation" msgstr "Navegación principal" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -197,6 +203,7 @@ msgid "REA on GitHub" msgstr "REA en GitHub" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -217,6 +224,7 @@ msgid "Join REA on Discord" msgstr "Únete a REA en Discord" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -236,7 +244,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "Sigue a REA en X" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "Volver arriba" @@ -11764,6 +11772,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "Mismo espaciado: 256 ÷ 16 = 16 unidades de ángulo = 22,5°" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -11784,6 +11793,7 @@ msgid "Showcases" msgstr "Casos prácticos" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -11804,6 +11814,7 @@ msgid "Blog" msgstr "Blog" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -11824,6 +11835,7 @@ msgid "Get started" msgstr "Primeros pasos" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -11843,7 +11855,8 @@ msgctxt "shared" msgid "Guides" msgstr "Guías" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -11863,7 +11876,8 @@ msgctxt "shared" msgid "Source" msgstr "Código fuente" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -11883,7 +11897,8 @@ msgctxt "shared" msgid "MIT license" msgstr "Licencia MIT" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -11903,7 +11918,8 @@ msgctxt "shared" msgid "Join the community" msgstr "Únete a la comunidad" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -12871,6 +12887,1400 @@ msgstr "" " o conecte el servidor MCP de Everywhere para inspeccionar el tráfico " "capturado con su agente." +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "Modelos especializados{ph0}Ensayo" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "¿Necesita la ingeniería inversa un modelo más grande?" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "" +"Lo que la reconstrucción de Touhou sugiere sobre los modelos generales, los " +"especializados y el aprendizaje a partir de los resultados del compilador." + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Por N0zoM1z0 · 13 de octubre de 2026" + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "Saltar al contenido" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "{ph0}Inicio{ph1} / {ph2}Blog{ph3} / Modelos e ingeniería inversa" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "ensayo" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "¿La ingeniería inversa necesita un modelo más grande?" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Por N0zoM1z0 · 13 de octubre de 2026" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "Ideas clave" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "" +"{ph0}La capacidad del modelo afecta qué hipótesis puede proponer un agente " +"de IA.{ph1} Las sesiones posteriores resolvieron problemas que el trabajo " +"anterior había dejado sin resolver." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "" +"{ph0}Un compilador familiar ofrece patrones concretos para que los aprenda " +"un modelo especializado.{ph1} Algunas coincidencias exactas de código de " +"máquina dependen de patrones de código fuente específicos y reutilizables." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "" +"{ph0}Incluya el conocimiento del repositorio en una comparación justa.{ph1} " +"Es posible que un modelo más pequeño con una buena recuperación de " +"conocimiento ya tenga suficiente información para avanzar." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "" +"{ph0}Entrene el modelo para elegir el siguiente experimento útil y pruebe su" +" verificador.{ph1} La retroalimentación es útil solo en la medida en que el " +"verificador verifica lo correcto." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "" +"{ph0}Evaluar los resultados de reconstrucción verificados junto con el " +"tiempo y el costo.{ph1} Eso es lo que quiero medir para todo el flujo de " +"trabajo del agente de IA." + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "En este artículo" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}Qué cambiaron los modelos más capaces{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}¿Por qué especializarse?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}¿Dónde debería almacenarse esta experiencia?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}Aprendiendo el próximo experimento útil{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}Ingeniería inversa y aprendizaje por refuerzo{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}Cuando el verificador está equivocado{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}Una comparación que vale la pena realizar{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}¿Qué tipo de agente de IA sugiere esto?{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "Qué cambiaron los modelos más capaces" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"Desde agosto de 2026, he estado explorando cuánta ingeniería inversa puede " +"realizar un agente con acceso a un programa y una forma de comprobar su " +"funcionamiento. La mayor parte de mi experiencia proviene de la " +"reconstrucción de juegos, especialmente Touhou. A medida que he ido " +"cambiando de modelo, los repositorios han ido manteniendo un registro de lo " +"que cada sesión logró recuperar." + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"Gran parte de ese trabajo apunta a una reconstrucción exacta: compilamos la " +"fuente mantenida bajo una cadena de herramientas histórica con versiones " +"fijas y comprobamos si reproduce la función de destino. Cuando un modelo " +"posterior tiene éxito donde el trabajo anterior se estancó, los cambios en " +"las fuentes muestran qué hizo posible ese progreso." + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "Los valores temporales debían seguir siendo válidos al mismo tiempo" + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"Gran parte de la lógica de la función de ataque TH09 ya había sido " +"reconstruida, pero el compilador aún almacenaba resultados temporales de " +"manera diferente al original. El problema restante era cuánto tiempo " +"necesitaban esos resultados para permanecer vivos y cuándo se podía " +"reutilizar su almacenamiento." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"Un registro de sesión {ph0}GPT-6-Sol{ph1} informó esta discrepancia después " +"de probar varias disposiciones de código fuente ordinarias. Cuando " +"{ph2}GPT-6.1-Sol examinó el problema nuevamente{ph3}, propuso una hipótesis " +"útil sobre la vida útil de estas variables temporales." + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"La función produjo resultados temporales y los copió en posiciones de " +"animación. En C++, un resultado temporal permanece vivo hasta que finaliza " +"la expresión que lo utiliza. Agrupar las operaciones reales en una expresión" +" mantuvo esos resultados vivos juntos, por lo que el compilador ya no pudo " +"reutilizar el mismo almacenamiento para todos ellos." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"Un resultado aún compartía almacenamiento con un valor utilizado más " +"adelante para comprobaciones de colisiones. Darle a ese valor su propia vida" +" útil resolvió la superposición restante. Después de varios experimentos " +"específicos, {ph0}una recompilación limpia del código fuente confirmó que la" +" función completa coincidía{ph1}." + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"Me interesa saber cómo el descubrimiento y las pruebas se apoyaron " +"mutuamente. La hipótesis sobre la vida temporal de los objetos dio al agente" +" de IA una nueva dirección. Los comentarios del compilador le ayudaron a " +"refinar esa hipótesis hasta convertirla en una disposición de código fuente " +"que coincidiera." + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "Un gráfico de flujo de control diferente" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"Una segunda función TH09 muestra por qué esa nueva dirección puede ser " +"importante. Aquí el obstáculo fue cómo varias ramas compartieron su trabajo " +"final. El trabajo anterior de {ph0}GPT-6.1-Sol{ph1} consiguió que partes de " +"la función coincidieran, pero las ramas aún se unían de manera diferente al " +"original." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}GPT-6-Astra cambió el gráfico de flujo de control circundante{ph1}. Los" +" caminos principales conducían ahora a una actualización final compartida y " +"al regreso. En esa estructura fuente, el compilador combinó las ramas de la " +"misma manera que el original. La función completa coincidió y una " +"{ph2}verificación de reconstrucción separada lo confirmó{ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}Cambiar la representación abrió un espacio de búsqueda más " +"productivo.{ph1} Ambos casos me dan una razón para tomar en serio la " +"capacidad del modelo general: un agente puede seguir probando variaciones " +"locales durante mucho tiempo antes de encontrar una mejor manera de expresar" +" el trabajo circundante." + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"Las sesiones posteriores también heredaron el código anterior y los intentos" +" fallidos documentados. Esa experiencia acumulada formaba parte de su " +"ventaja. El historial permite examinar los hallazgos y sus comprobaciones; " +"una comparación controlada ayudaría a separar el efecto del modelo del de la" +" experiencia que recibió." + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"Esto es lo que hace que la pregunta me resulte interesante. Algunos avances " +"se produjeron al encontrar una nueva representación. Gran parte del trabajo " +"restante implicó probar diferentes disposiciones de código fuente con un " +"compilador familiar. ¿Cuánto de esto requiere una amplia capacidad de " +"razonamiento? ¿Cuánto podría aprender un modelo trabajando repetidamente con" +" ese compilador y código?" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "¿Por qué podría funcionar bien un modelo de IA especializado?" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"Touhou nos da una razón concreta para esperar que esa experiencia ayude. " +"Gran parte del código del juego proviene del mismo autor, ZUN, por lo que " +"los hábitos recurrentes son una suposición inicial razonable. Los " +"repositorios respaldan esto con ejemplos útiles: bucles relacionados y " +"arreglos de ayuda han proporcionado hipótesis en todos los juegos." + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "" +"Esos patrones fuente se vuelven más específicos cuando incluimos el " +"compilador. Bajo una versión particular y un conjunto de opciones, pequeños " +"cambios en la fuente pueden producir diferencias repetibles en el código de " +"máquina. Algunas de esas diferencias son sorprendentemente oscuras." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"En TH095, por ejemplo, {ph0}incluso el nombre de una variable local podría " +"afectar dónde la almacenó VC7.1{ph1}. Mover su declaración no resolvió el " +"diseño del almacenamiento. Sin embargo, una función en segundo plano " +"anterior había revelado un patrón de nombres que afectaba la elección del " +"compilador. Eso sugirió una hipótesis más prometedora para {ph2}reconstruir " +"{ph3}{ph4}." + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "" +"La reutilización de ese patrón para la variable de tamaño de archivo produjo" +" el diseño requerido sin agregar almacenamiento. Entonces coincidió la " +"función completa." + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "" +"Este es un detalle muy específico que un modelo de IA de propósito general " +"puede no conocer cuando encuentra el problema por primera vez. Un modelo " +"especializado para este compilador podría ver muchos de estos casos y " +"aprender qué variaciones del código fuente vale la pena probar primero." + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"La oportunidad es especialmente clara en los problemas finales de " +"emparejamiento en los que ya entendemos el comportamiento. Entonces nos " +"preguntamos qué disposición ordinaria del código fuente convierte este " +"compilador en las instrucciones observadas. La especialización podría ayudar" +" al modelo a proponer esas formas de manera más eficiente, mientras que el " +"objetivo aún determina qué hipótesis sobreviven." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"Los patrones útiles deben conservar su contexto. TH08 utiliza una versión " +"Visual C++ anterior a TH095 y TH09. TH04 utiliza un compilador diferente de " +"la era DOS. Su {ph0}reconstrucción del código del jugador{ph1} necesitaba " +"diferentes hipótesis sobre los patrones del código fuente y cómo el código " +"compilado se vinculaba a un ejecutable. Tener el mismo autor nos da una " +"expectativa inicial, pero cada objetivo nos dice si aplica. Un modelo " +"especializado necesitaría distinguir estos contextos." + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "¿Dónde debería almacenarse esta experiencia?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"Antes de decidir enseñar esos patrones mediante el entrenamiento de modelos," +" miraría el conocimiento que ya guardamos en el repositorio. En el " +"{ph0}ensayo anterior{ph1}, escribí sobre cómo se convertiría en la memoria " +"de trabajo del proyecto. Esa memoria incluye lecciones del compilador, junto" +" con la fuente y los experimentos fallidos que los hicieron útiles." + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"Al recuperar ese registro, un agente puede comenzar con un resultado " +"conocido e inspeccionar cómo llegamos a él. También puede evitar " +"alternativas que ya han fracasado en el mismo contexto. El punto de partida " +"mejora sin cambiar los parámetros entrenados del modelo." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"Mientras reconstruía la función de TH09 para crear enemigos, una sesión " +"{ph0}GPT-6-Luna-max{ph1} tomó una hipótesis del código fuente relacionado de" +" TH08. Ese código anterior sugirió cómo organizar el bucle y manejar las " +"fallas dentro de él. La propia evidencia de TH09 proporcionó los detalles " +"específicos del juego. Las reconstrucciones de la fuente confirmaron que la " +"función completa coincidía." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}\"El modelo no sabía esa peculiaridad del compilador\" y \"el modelo no" +" podía usarlo\" son problemas diferentes.{ph1} La recuperación puede " +"resolver el primero, pero convertir ese hecho en un candidato útil aún " +"requiere trabajo. Y si el código fuente candidato falla, el modelo debe " +"decidir qué significa el resultado para su próximo intento. Conocer el " +"patrón relevante es sólo el comienzo de ese proceso." + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"Por esa razón, incluiría en cualquier comparación un modelo de IA de " +"propósito general más pequeño con buena recuperación. Darle la misma " +"biblioteca de experiencia nos ayudaría a identificar qué aporta la " +"capacitación: mejor generación de candidatos, mejores decisiones después de " +"la retroalimentación, o ambas." + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "Aprendiendo el próximo experimento útil" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"Esas decisiones después del feedback son las que más me gustaría estudiar. " +"En la reconstrucción agente, el modelo propone una explicación y la compara " +"con el programa. Incluso cuando el código fuente candidato falla, el " +"resultado puede reducir las posibilidades restantes y sugerir un próximo " +"experimento más útil." + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "" +"Considere nuevamente el ejemplo de los resultados temporales. Su fuente " +"final muestra el arreglo que funcionó, pero la ruta a esa fuente contiene " +"más información. Cada uno de los siguientes experimentos ayudó a identificar" +" lo que aún era necesario cambiar." + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "experimento" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "Lo que nos enseñó su resultado" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "Pruebe una forma diferente de copiar los resultados." + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "El código de copia cambia, pero la función aún difiere." + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "Utilice los valores devueltos directamente" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "" +"La copia sigue el patrón original, pero el almacenamiento temporal aún " +"difiere." + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "Mantener todas las variables temporales válidas al mismo tiempo." + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "" +"Se almacenan por separado, pero uno aún se superpone a un valor utilizado " +"más adelante para las comprobaciones de colisiones." + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "Mantenga el valor de verificación de colisiones separado" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "" +"Una recompilación limpia del código fuente confirma la coincidencia " +"completa." + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "" +"Experimentos seleccionados de la reconstrucción de la función de ataque " +"anterior, agrupados según lo que nos enseñaron." + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"Un registro de capacitación que mantenga esta secuencia puede enseñar más " +"que la fuente final por sí sola. Conecta cada cambio propuesto con un " +"resultado observado y la siguiente decisión. Mantener variaciones ineficaces" +" también es importante: le dicen a un agente posterior qué hipótesis ya han " +"sido probadas en ese contexto." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}Me gustaría que el modelo aprendiera a utilizar la " +"retroalimentación.{ph1} Un resultado neutral es una razón para reconsiderar " +"la variación; una discrepancia modificada puede indicar otra causa. Cuando " +"las ediciones locales dejan de ser informativas, el agente debería poder " +"revisar la representación de la fuente o inspeccionar la evidencia " +"nuevamente." + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"Aprender a tomar esas decisiones requiere autonomía. A veces, el siguiente " +"paso útil es inspeccionar a otra persona que llama en lugar de compilar otra" +" edición. Una secuencia rígida de reescrituras requeridas eliminaría esa " +"elección, junto con parte del comportamiento que queremos que aprenda el " +"modelo." + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "" +"Por qué la ingeniería inversa es interesante para el aprendizaje por " +"refuerzo" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"La reconstrucción acotada nos brinda un entorno práctico para estudiar estas" +" opciones. Una vez que se corrigen las versiones de destino y del " +"compilador, muchos experimentos de origen producen comentarios rápidos y " +"repetibles. El agente puede compilar un candidato, inspeccionar la " +"discrepancia y utilizar esa observación para elegir el siguiente paso." + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"El aprendizaje por refuerzo podría entrenar ese proceso de toma de " +"decisiones a través de la retroalimentación que recibe. Un candidato " +"aceptado mediante un control definido nos da un resultado concreto, mientras" +" que la secuencia de intentos nos permite observar cuánto trabajo ha sido " +"necesario para alcanzarlo." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"Ya existen investigaciones que respaldan esta dirección. " +"{ph0}LLM4Decompile{ph1} estudia modelos especializados para la " +"descompilación. {ph2}AutoDecompiler{ph3} entrena el refinamiento de varios " +"turnos utilizando el compilador y los comentarios de ejecución. Sus estudios" +" se centran en la recuperación funcional. Para este trabajo, los usaría como" +" punto de partida para la tarea relacionada de encontrar una fuente que " +"coincida con la salida de un compilador histórico." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"Sin embargo, para alcanzar una tarea tan bien definida, es posible que " +"primero necesitemos establecer qué recursos posee una función o diseñar una " +"nueva forma de observar el comportamiento del programa durante su ejecución." +" En TH08, por ejemplo, una {ph0}diferencia de colisión llevó a cómo el " +"programa original manejaba los cálculos de punto flotante{ph1}. Antes de que" +" el agente pudiera probar una corrección útil, tenía que decidir qué medir." + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "" +"Esto sugiere otra función para un modelo con amplias capacidades: ayudar a " +"que el problema sea verificable en primer lugar. Una vez que exista esa " +"verificación, podemos investigar hasta dónde puede llegar una política de " +"búsqueda aprendida." + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "Cuando el verificador está equivocado" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"Al entrenar con una comprobación, su cobertura pasa a formar parte del " +"entorno de aprendizaje. Llamo oracle a esa referencia o verificador. Aunque " +"la respuesta sea repetible, debemos entender qué verifica realmente." + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"TH08 mostró cuánto se puede ocultar fuera de esa cobertura. Algunas " +"funciones reconstruidas pasaron sus comparaciones exactas con constantes " +"flotantes incorrectas. El comparador ajustó las direcciones reubicadas antes" +" de verificar las instrucciones, pero verificó los valores detrás de esas " +"direcciones solo cuando se habían registrado explícitamente para su " +"verificación. Otras referencias literales podrían pasar sin que se examinen " +"sus valores." + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"Para abordar esta brecha, una {ph0}auditoría más amplia{ph1} encontró " +"constantes incorrectas en funciones que ya habían pasado la verificación. En" +" un cálculo, el código fuente reconstruido agregó {ph2}, mientras que el " +"original agregó {ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}Un modelo recompensado por la comprobación anterior podría aprender a " +"producir una reconstrucción incorrecta.{ph1} No entrenamos un modelo RL " +"usando ese verificador. El fallo que observamos estaba en la propia " +"comprobación. Pero si lo usáramos como recompensa, el mismo punto ciego " +"pasaría a formar parte del entorno de aprendizaje." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"Una prueba funcional puede tener un punto ciego similar. {ph0}La " +"investigación que utilizó fuzzing diferencial en descompiladores LLM{ph1} " +"encontró diferencias de comportamiento fuera de las pruebas proporcionadas. " +"Por lo tanto, debemos entender una prueba aprobatoria en términos de los " +"casos en los que se aplica. De manera similar, una coincidencia de " +"instrucciones debe entenderse en términos de los bytes y datos que verifica." + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"Antes de utilizar cualquier tipo de control de verificación como recompensa," +" lo probaría con resultados deliberadamente incorrectos. También mantendría " +"la aceptación final separada del código fuente que el agente de IA puede " +"editar. El modelo debe pasar la verificación reconstruyendo el programa " +"correctamente. De lo contrario, simplemente copiar una matriz de bytes del " +"destino podría engañar a un sistema de puntuación ingenuo sin recuperar el " +"código fuente útil." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "" +"{ph0}Mejorar al alumno y mejorar su verificador pertenecen al mismo problema" +" de investigación.{ph1} A medida que el alumno mejora en la optimización de " +"los comentarios que le damos, comprender esos comentarios también se vuelve " +"más importante." + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "Una comparación que vale la pena realizar" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"Con esas comprobaciones implementadas, comenzaría la comparación en una " +"familia de tareas fija VC7.1. Primero, establecería líneas de base para un " +"modelo de IA de propósito general sólido y uno más pequeño. Agregar " +"conocimiento del repositorio al modelo más pequeño mostraría qué cambios en " +"la recuperación. A partir de ahí, la especialización supervisada y una " +"versión capacitada con RL nos permitirían examinar qué agrega la " +"capacitación." + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"Para que esas comparaciones sean informativas, cada modelo recibiría la " +"misma evidencia y herramientas objetivo. Para las comparaciones específicas " +"de la capacitación, también mantendría fijo el modelo base y el conocimiento" +" disponible. Las pruebas repetidas ayudarían a distinguir una estrategia de " +"búsqueda confiable de una solución candidata que tiene éxito por casualidad." + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"Luego separaría dos condiciones iniciales: reconstruir una función a partir " +"de sus instrucciones y cerrar las últimas diferencias en la fuente " +"mantenida. Un modelo de IA especializado podría ser excelente en la segunda " +"tarea, mientras que un modelo de IA de propósito general hace gran parte del" +" trabajo necesario para alcanzarla. Medirlos por separado revelaría esa " +"división del trabajo." + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"Ambas tareas necesitan ejemplos de prueba excluidos del entrenamiento y la " +"recuperación. Los juegos Touhou relacionados comparten el código del motor. " +"Excluir un juego del entrenamiento aún podría dejar funciones casi idénticas" +" en el conjunto de entrenamiento. En cambio, excluiría grupos enteros de " +"código fuente relacionado y mantendría sus respuestas verificadas fuera de " +"los datos de entrenamiento y de la biblioteca de recuperación." + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"Para estos ejemplos, el resultado serían coincidencias completas y " +"verificadas de forma independiente. La igualdad de presupuestos para las " +"propuestas de los candidatos o los intentos de compilación ayudaría a " +"comparar la calidad de la búsqueda. Medir el tiempo y el costo total, " +"incluida la compilación, mostraría si esa calidad produce un flujo de " +"trabajo eficiente. Los costos de capacitación deben medirse por separado." + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"Ambas medidas importan. Una propuesta barata puede generar un flujo de " +"trabajo costoso si genera más compilaciones que no proporcionan información " +"útil. Por el contrario, un modelo más lento puede resultar más económico si " +"encuentra antes un experimento útil. La comparación debe incluir estos " +"costos." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"Contar los resultados aceptados también ayuda a interpretar los avances " +"intermedios. Un {ph0}candidato para guardar repeticiones{ph1} de TH09 " +"parecía prometedor porque la función compilada tenía el tamaño esperado, " +"pero la comparación completa aún encontró diferencias importantes. La forma " +"en que el compilador ordena las instrucciones puede hacer que un candidato " +"parezca más cercano sin resolver el problema de fondo. Estos diagnósticos " +"orientan el siguiente experimento; antes de premiar una mayor cercanía, la " +"contrastaría con la comprobación completa de aceptación." + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"Me interesaría conocer el patrón de estos resultados. Si un modelo de IA " +"especializado funciona bien dentro de una familia de compiladores familiar, " +"¿esa ventaja sobrevive a un cambio en la cadena de herramientas? Y una vez " +"que ambos modelos de IA tengan una buena recuperación, ¿cuánto aporta aún el" +" entrenamiento? Las respuestas nos ayudarían a decidir dónde es más útil " +"cada tipo de modelo." + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "¿Qué tipo de agente de IA sugiere esto?" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"Si los modelos resultan útiles en diferentes etapas, un acuerdo útil podría " +"ser un agente amplio con acceso a un modelo de IA especializado. Una vez que" +" una tarea se convierte en una búsqueda familiar del compilador, podría " +"solicitar candidatos al modelo de IA especializado. Si los resultados dejan " +"de tener sentido, el agente más amplio podría volver a la evidencia objetivo" +" o investigar la medición en sí." + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "" +"En ese arreglo, la especialización se convierte en una herramienta que el " +"agente puede elegir a medida que se desarrolla la investigación. El agente " +"conserva la libertad de cambiar la dirección que hizo posibles los avances " +"anteriores." + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"Esto se deriva naturalmente del cambio industrial que describí en el ensayo " +"anterior. Poder realizar muchos más experimentos cambia la forma en que " +"organizamos el trabajo. También nos da una razón para preguntar qué " +"decisiones requieren un juicio amplio y cuáles mejoran a través de " +"experiencias repetidas con un oficio en particular." + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"Por ahora, el modelo general más potente se ha ganado su lugar en mi flujo " +"de trabajo al resolver problemas que había dejado pendientes. Esos éxitos me" +" llevan a examinar el proceso: ¿cuánto dependía de la amplitud del modelo y " +"cuánto podría asumir uno entrenado específicamente para esta clase de " +"reconstrucción?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "" +"{ph0}Los repositorios nos brindan una forma de probar la pregunta.{ph1} Me " +"gustaría usar ese registro para realizar la comparación y ver qué " +"aprendemos." + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "Atribución de evidencia y modelo" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"Los ejemplos describen comparaciones históricas a nivel de función " +"registradas en las confirmaciones vinculadas. Las comprobaciones del tiempo " +"de ejecución del juego completo son hitos separados. Los registros fuente y " +"coincidentes se revisaron el 13 de octubre de 2026." + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"La etiqueta TH09 {ph0} significa GPT-6-Astra. El modelo asociado con {ph1} " +"cambió con el tiempo, por lo que esa etiqueta por sí sola no puede " +"identificar el modelo utilizado en una ejecución específica. Los nombres de " +"modelos explícitos en las otras confirmaciones citadas proporcionan la " +"atribución registrada. Estos historiales no incluyen mediciones consistentes" +" de costo o esfuerzo para cada ejecución." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "" +"{ph0}TH09 duración de los objetos temporales:{ph1} la {ph2}revisión de " +"contexto anterior{ph3} y la {ph4}reconstrucción completa verificada mediante" +" una recompilación limpia del código fuente{ph5}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"{ph0}TH09 Front devolución de llamada:{ph1} {ph2}regiones de diagnóstico que" +" no coincidieron{ph3}, {ph4}Astra nuevo gráfico de flujo de control{ph5} y " +"su {ph6}verificación de recompilación aceptada{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}Conocimiento del compilador:{ph1} {ph2}TH095 reutilización del " +"comportamiento del identificador-depósito{ph3}, {ph4}TH04 código fuente del " +"jugador y orden del enlazador{ph5} y {ph6}Luna reconstrucción completa de la" +" función de creación de enemigos de TH09{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}Comprobaciones y diagnósticos:{ph1} {ph2}TH08 auditoría constante de " +"punto flotante{ph3}, {ph4}TH08 investigación numérica{ph5} y {ph6}TH09 " +"reconstrucción para guardar reproducciones{ph7}." + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "" +"Las comparaciones propuestas de modelos especializados y entrenamiento RL " +"son experimentos futuros. Las historias de los proyectos los motivan. Para " +"este ensayo no se evaluó ningún modelo especializado entrenado." + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "¿La ingeniería inversa necesita un modelo más grande? | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "" +"Lo que me enseñó la reconstrucción Touhou sobre modelos generales, modelos " +"especializados y cómo aprender a proponer mejores hipótesis a partir de los " +"comentarios del compilador." + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "En esta página" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "Modelos y ensayo de ingeniería inversa." + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "Experimentos de reconstrucción seleccionados." + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "Volver arriba" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "" +"Las {ph0}notas detalladas de evidencia{ph1} incluyen las comparaciones " +"registradas y el contexto de los experimentos." + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "Por N0zoM1z0 · 13 de octubre de 2026 · Borrador para revisión" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "Guía de instalación" diff --git a/website/locales/fa/messages.po b/website/locales/fa/messages.po index e163a131b..02b489a3c 100644 --- a/website/locales/fa/messages.po +++ b/website/locales/fa/messages.po @@ -32,18 +32,18 @@ msgid "Thoughts on reverse engineering." msgstr "افکار در مهندسی معکوس." #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "بازسازی بازی{ph0}مقاله" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "انقلاب صنعتی در مهندسی معکوس" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " @@ -52,19 +52,20 @@ msgstr "" "چه دستی دوباره و بازسازی TH08, TH095 و TH04 به من آموخت در مورد عوامل, تأیید" " و دانش است که ترکیبات در سراسر پروژه." -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "مقاله را بخوانید" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "توسط N0zoM1z0 * 10 اکتبر 2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -99,6 +100,8 @@ msgstr "" "افکار در مهندسی معکوس ، با استفاده از تجربه عملی با REA و عوامل هوش مصنوعی." #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -135,6 +138,7 @@ msgstr "" "شما." #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -155,6 +159,7 @@ msgid "REA home" msgstr "صفحهٔ اصلی REA" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -175,6 +180,7 @@ msgid "Main navigation" msgstr "ناوبری اصلی" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -195,6 +201,7 @@ msgid "REA on GitHub" msgstr "REA در GitHub" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -215,6 +222,7 @@ msgid "Join REA on Discord" msgstr "به REA در Discord بپیوندید" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -234,7 +242,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "REA را در X دنبال کنید" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "بازگشت به بالا" @@ -11479,6 +11487,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "فاصله یکسان: 256 × 16 = 16 واحد زاویه = 22.5 درجه" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -11499,6 +11508,7 @@ msgid "Showcases" msgstr "نمونه‌ها" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -11519,6 +11529,7 @@ msgid "Blog" msgstr "وبلاگ" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -11539,6 +11550,7 @@ msgid "Get started" msgstr "شروع کنید" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -11558,7 +11570,8 @@ msgctxt "shared" msgid "Guides" msgstr "راهنماها" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -11578,7 +11591,8 @@ msgctxt "shared" msgid "Source" msgstr "کد منبع" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -11598,7 +11612,8 @@ msgctxt "shared" msgid "MIT license" msgstr "مجوز MIT" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -11618,7 +11633,8 @@ msgctxt "shared" msgid "Join the community" msgstr "به جامعه بپیوندید" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -12580,6 +12596,1332 @@ msgstr "" " در REA به‌صورت آفلاین، خروجی SAZ ?? HAR 1.2 بگیرید، یا سرور MCP نرم‌افزار " "Everywhere را متصل کنید تا ترافیک ضبط‌شده را با عامل خود بررسی کنید." +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "مدل‌های تخصصی{ph0}یادداشت" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "آیا مهندسی معکوس به مدل بزرگ‌تری نیاز دارد؟" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "" +"تأملاتی بر پایهٔ بازسازی Touhou دربارهٔ مدل‌های عمومی، مدل‌های تخصصی و " +"یادگیری از بازخورد کامپایلر." + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "توسط N0zoM1z0 · 13 اکتبر 2026" + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "پرش به محتوا" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "{ph0}صفحه اصلی{ph1} / {ph2}وبلاگ{ph3} / مدل‌ها و مهندسی معکوس" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "انشا" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "آیا مهندسی معکوس به مدل بزرگتری نیاز دارد؟" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "توسط N0zoM1z0 · 13 اکتبر 2026" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "نکات اصلی" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "" +"{ph0}قابلیت مدل بر فرضیه‌هایی که یک عامل هوش مصنوعی می‌تواند ارائه دهد تأثیر" +" می‌گذارد.{ph1} جلسات بعدی مشکلاتی را که کار قبلی حل نشده رها کرده بود حل " +"کرد." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "" +"{ph0}یک کامپایلر آشنا الگوهای مشخصی را برای یادگیری یک مدل تخصصی ارائه " +"می‌کند.{ph1} برخی از تطابق دقیق کد ماشین به الگوهای کد منبع خاص و قابل " +"استفاده مجدد بستگی دارد." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "" +"{ph0}دانش مخزن را در یک مقایسه منصفانه لحاظ کنید.{ph1} یک مدل کوچکتر با " +"بازیابی دانش خوب ممکن است اطلاعات کافی برای پیشرفت داشته باشد." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "" +"{ph0}مدل را آموزش دهید تا آزمایش مفید بعدی را انتخاب کند و بررسی‌کننده تأیید" +" آن را آزمایش کنید.{ph1} بازخورد فقط در حدی مفید است که بررسی‌کننده موارد " +"درست را تأیید کند." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "" +"{ph0}نتایج بازسازی تایید شده را در کنار زمان و هزینه ارزیابی کنید.{ph1} این " +"چیزی است که من می‌خواهم برای گردش کار کامل عامل هوش مصنوعی اندازه‌گیری کنم." + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "در این مقاله" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}مدل‌های قوی‌تر چه چیزی را تغییر دادند؟{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}چرا تخصص داشته باشید؟{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}این تجربه در کجا باید ذخیره شود؟{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}یادگیری آزمایش مفید بعدی{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}مهندسی معکوس و یادگیری تقویتی{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}هنگامی که بررسی کننده تأیید اشتباه است{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}مقایسه ای که ارزش اجرا دارد{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}این چه نوع عامل هوش مصنوعی را پیشنهاد می کند؟{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "مدل‌های قوی‌تر چه چیزی را تغییر دادند؟" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"از آگوست 2026، من در حال بررسی میزان مهندسی معکوس یک عامل با دسترسی به یک " +"برنامه و راهی برای بررسی کار آن هستم. بیشتر تجربه من از بازسازی بازی ها به " +"خصوص Touhou ناشی می شود. همانطور که من مدل‌ها را تغییر داده‌ام، مخازن رکوردی" +" از آنچه هر جلسه توانسته است بازیابی کند را نگه داشته است." + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"هدف بیشتر این کار بازسازی دقیق است: ما منبع نگهداری شده را تحت یک زنجیره " +"ابزار تاریخی با نسخه های ثابت کامپایل می کنیم و بررسی می کنیم که آیا تابع " +"هدف را بازتولید می کند یا خیر. هنگامی که مدل بعدی در جایی که کار قبلی متوقف " +"شده بود موفق می شود، تغییرات منبع نشان می دهد که چه چیزی این پیشرفت را ممکن " +"کرده است." + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "متغیرهای موقت به طول عمر همپوشانی نیاز داشتند" + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"بیشتر منطق یک تابع حمله TH09 قبلاً بازسازی شده بود، اما کامپایلر همچنان " +"نتایج موقت را متفاوت از نسخه اصلی ذخیره می کرد. مشکل باقی‌مانده این بود که " +"این نتایج چقدر طول می‌کشد تا زنده بمانند و چه زمانی می‌توان از ذخیره‌سازی " +"آنها استفاده مجدد کرد." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"یک {ph0}GPT-6-Sol رکورد جلسه{ph1} این عدم تطابق را پس از آزمایش چندین ترتیب " +"کد منبع معمولی گزارش کرد. وقتی {ph2}GPT-6.1-Sol دوباره مشکل را بررسی " +"کرد{ph3}، یک فرضیه مفید در مورد طول عمر این متغیرهای موقت ارائه کرد." + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"این تابع نتایج موقتی تولید کرد و آنها را در موقعیت های انیمیشن کپی کرد. در " +"C++، یک نتیجه موقت زنده می ماند تا زمانی که عبارت استفاده شده از آن تمام " +"شود. گروه‌بندی عملیات واقعی در یک عبارت، آن نتایج را با هم زنده نگه می‌دارد،" +" بنابراین کامپایلر دیگر نمی‌تواند از فضای ذخیره‌سازی یکسان برای همه آنها " +"استفاده مجدد کند." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"یک نتیجه همچنان فضای ذخیره‌سازی را با مقداری به اشتراک گذاشته است که بعداً " +"برای بررسی‌های برخورد استفاده می‌شود. دادن این ارزش به طول عمر خودش، " +"همپوشانی باقیمانده را حل کرد. پس از چندین آزمایش هدفمند، {ph0}کامپایل مجدد " +"تمیز از منبع تأیید کرد که تابع کامل مطابقت دارد{ph1}." + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"من علاقه مندم که چگونه این کشف و آزمایش ها از یکدیگر حمایت کردند. فرضیه در " +"مورد طول عمر اشیاء موقت به عامل هوش مصنوعی مسیر جدیدی داد. بازخورد کامپایلر " +"به آن کمک کرد تا این فرضیه را به ترتیب کد منبع که مطابقت دارد، اصلاح کند." + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "یک نمودار کنترل جریان متفاوت" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"تابع دوم TH09 نشان می دهد که چرا آن جهت جدید می تواند مهم باشد. در اینجا، " +"مانع این بود که چگونه چندین شعبه کار نهایی خود را به اشتراک گذاشتند. کار " +"قبلی {ph0}GPT-6.1-Sol{ph1} بخش‌هایی از تابع را مطابقت داد، اما شاخه‌ها " +"همچنان متفاوت از نسخه اصلی به یکدیگر متصل شدند." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}GPT-6-Astra نمودار کنترل جریان اطراف را تغییر داد{ph1}. مسیرهای اصلی " +"اکنون به یک به‌روزرسانی نهایی مشترک و بازگشت منجر می‌شوند. در آن ساختار " +"منبع، کامپایلر شاخه ها را به همان روش اصلی ترکیب می کند. تابع کامل مطابقت " +"داشت و {ph2}بررسی بازسازی جداگانه آن را تأیید کرد{ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}تغییر نمایش، فضای جستجوی سازنده‌تری را باز کرد.{ph1} هر دو مورد دلیلی " +"برای جدی گرفتن قابلیت مدل کلی به من می‌دهد: یک نماینده می‌تواند قبل از یافتن" +" راهی بهتر برای بیان کار اطراف، برای مدت طولانی تغییرات محلی را امتحان کند." + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"در همان زمان، جلسات بعدی با منبع قبلی شروع شد و خرابی ها ثبت شد. این کار " +"انباشته بخشی از مزیت آنها بود. تاریخ به ما اجازه می دهد تا کشفیات و بررسی " +"های آنها را بررسی کنیم. یک مقایسه کنترل شده به تفکیک اثر مدل از تجربه ای که " +"به ارث برده است کمک می کند." + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"این چیزی است که سوال را برای من جالب می کند. برخی پیشرفت ها از یافتن " +"نمایندگی جدید حاصل شد. بسیاری از کارهای باقی مانده شامل آزمایش ترتیبات مختلف" +" کد منبع در برابر یک کامپایلر آشنا بود. چه مقدار از این به توانایی استدلال " +"گسترده نیاز دارد؟ یک مدل با کار مکرر با آن کامپایلر و کد چقدر می تواند یاد " +"بگیرد؟" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "چرا یک مدل تخصصی هوش مصنوعی ممکن است خوب عمل کند؟" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"Touhou دلیل مشخصی به ما می دهد که انتظار داشته باشیم آن تجربه کمک کند. بیشتر" +" کد بازی از همان نویسنده، ZUN می آید، بنابراین عادت های تکرار شونده یک فرض " +"شروع منطقی هستند. مخازن با مثال‌های مفید این موضوع را تأیید می‌کنند: " +"حلقه‌های مرتبط و ترتیبات کمکی فرضیه‌هایی را در بین بازی‌ها ارائه کرده‌اند." + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "" +"وقتی کامپایلر را وارد کنیم، این الگوهای منبع خاص تر می شوند. تحت یک نسخه خاص" +" و مجموعه ای از گزینه ها، تغییرات کوچک در منبع می تواند تفاوت های قابل تکرار" +" در کد ماشین ایجاد کند. برخی از این تفاوت ها به طرز شگفت آوری مبهم هستند." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"به عنوان مثال، در TH095، {ph0}حتی نام یک متغیر محلی می‌تواند بر جایی که " +"VC7.1 آن را ذخیره کرده است، تأثیر بگذارد{ph1}. انتقال اعلان آن طرح ذخیره " +"سازی را حل نکرد. با این حال، یک تابع پس زمینه قبلی یک الگوی نامگذاری را نشان" +" داده بود که بر انتخاب کامپایلر تأثیر می گذاشت. این فرضیه امیدوارکننده تری " +"را برای {ph2}بازسازی {ph3}{ph4} پیشنهاد کرد." + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "" +"استفاده مجدد از آن الگو برای متغیر اندازه فایل، طرح مورد نیاز را بدون افزودن" +" فضای ذخیره سازی ایجاد کرد. سپس تابع کامل مطابقت داشت." + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "" +"این یک جزئیات بسیار خاص است که یک مدل هوش مصنوعی همه منظوره ممکن است زمانی " +"که برای اولین بار با مشکل مواجه می شود از آن مطلع نباشد. یک مدل تخصصی برای " +"این کامپایلر می‌تواند موارد بسیاری از این قبیل را ببیند و یاد بگیرد که کدام " +"تغییرات کد منبع ارزش آزمایش را دارند." + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"این فرصت به ویژه در مسائل تطبیق نهایی که ما قبلاً رفتار را درک کرده ایم، " +"واضح است. سپس می‌پرسیم این کامپایلر کدام ترتیب کد منبع معمولی را به " +"دستورالعمل‌های مشاهده شده تبدیل می‌کند. تخصص می تواند به مدل کمک کند تا آن " +"اشکال را به طور کارآمدتر پیشنهاد کند، در حالی که هدف هنوز تعیین می کند که " +"کدام فرضیه ها باقی می مانند." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"الگوهای مفید باید زمینه خود را حفظ کنند. TH08 از نسخه Visual C++ قبلی نسبت " +"به TH095 و TH09 استفاده می کند. TH04 از یک کامپایلر متفاوت از دوران DOS " +"استفاده می کند. {ph0}بازسازی کد بازیکن{ph1} آن به فرضیه‌های مختلفی در مورد " +"الگوهای کد منبع و نحوه پیوند کد کامپایل‌شده به یک فایل اجرایی نیاز داشت. " +"داشتن یک نویسنده یک انتظار اولیه را به ما می‌دهد، اما هر هدف به ما می‌گوید " +"که آیا کاربرد دارد یا خیر. یک مدل تخصصی باید این زمینه ها را متمایز کند." + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "این تجربه در کجا باید ذخیره شود؟" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"قبل از تصمیم به آموزش آن الگوها از طریق آموزش مدل، به دانشی که قبلاً در مخزن" +" نگهداری می‌کنیم نگاهی می‌اندازم. در {ph0}مقاله قبلی{ph1}، درباره تبدیل شدن " +"آن به حافظه کاری پروژه نوشتم. این حافظه شامل درس های کامپایلر، همراه با منبع" +" و آزمایش های ناموفق است که آنها را مفید ساخته است." + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"با بازیابی آن رکورد، یک نماینده می تواند با یک نتیجه شناخته شده شروع کند و " +"نحوه رسیدن ما به آن را بررسی کند. همچنین می تواند از جایگزین هایی که قبلاً " +"در همان زمینه شکست خورده اند اجتناب کند. نقطه شروع بدون تغییر پارامترهای " +"آموزش دیده مدل بهبود می یابد." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"هنگام بازسازی عملکرد TH09 برای ایجاد دشمن، یک جلسه {ph0}GPT-6-Luna-max{ph1} " +"یک فرضیه را از کد منبع TH08 مرتبط گرفت. آن کد قبلی نحوه سازماندهی حلقه و " +"مدیریت خرابی های داخل آن را پیشنهاد می کرد. شواهد خود TH09 جزئیات مربوط به " +"بازی را ارائه کرد. بازسازی از منبع تأیید کرد که عملکرد کامل مطابقت دارد." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}\"مدل نمی‌دانست که ویژگی کامپایلر\" و \"مدل نمی‌تواند از آن استفاده " +"کند\" مشکلات متفاوتی هستند.{ph1} بازیابی ممکن است مشکل اول را حل کند، اما " +"تبدیل این واقعیت به یک نامزد مفید هنوز کار می‌برد. و اگر کد منبع کاندید شکست" +" بخورد، مدل باید تصمیم بگیرد که نتیجه برای تلاش بعدی چه معنایی دارد. دانستن " +"الگوی مربوطه تنها آغاز آن فرآیند است." + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"به همین دلیل، من یک مدل هوش مصنوعی همه منظوره کوچکتر را با بازیابی خوب در هر" +" مقایسه قرار می دهم. ارائه همان کتابخانه تجربی به ما کمک می کند تا تشخیص " +"دهیم که آموزش چه چیزی را اضافه می کند: تولید نامزد بهتر، تصمیم گیری بهتر پس " +"از بازخورد، یا هر دو." + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "یادگیری آزمایش مفید بعدی" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"آن تصمیمات پس از بازخورد همان چیزی است که من بیشتر دوست دارم مطالعه کنم. در " +"بازسازی عاملی، مدل توضیحی را پیشنهاد می کند و آن را در برابر برنامه آزمایش " +"می کند. حتی زمانی که کد منبع نامزد ناموفق باشد، نتیجه می تواند احتمالات " +"باقیمانده را محدود کند و آزمایش بعدی مفیدتری را پیشنهاد کند." + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "" +"مثال موقت نتایج را دوباره در نظر بگیرید. منبع نهایی آن ترتیبی را نشان می دهد" +" که کارآمد است، اما مسیر رسیدن به آن منبع حاوی اطلاعات بیشتری است. هر یک از " +"آزمایش‌های زیر به شناسایی آنچه که هنوز باید تغییر کند کمک کرد." + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "آزمایش کنید" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "آنچه نتیجه آن به ما آموخت" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "روش دیگری را برای کپی کردن نتایج امتحان کنید" + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "کد کپی تغییر می کند، اما عملکرد همچنان متفاوت است." + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "از مقادیر برگشتی مستقیما استفاده کنید" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "" +"کپی کردن از الگوی اصلی پیروی می کند، اما ذخیره سازی موقت همچنان متفاوت است." + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "همه متغیرهای موقت را همزمان معتبر نگه دارید" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "" +"آنها فضای ذخیره جداگانه ای دریافت می کنند، اما هنوز هم مقداری که بعداً برای " +"بررسی برخورد استفاده می شود، همپوشانی دارد." + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "مقدار collision-check را جدا نگه دارید" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "یک کامپایل مجدد تمیز از منبع، مطابقت کامل را تأیید می کند." + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "" +"آزمایش‌های منتخب از بازسازی عملکرد حمله در بالا، گروه‌بندی شده بر اساس آنچه " +"به ما آموختند." + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"یک رکورد آموزشی که این توالی را حفظ می کند می تواند بیشتر از منبع نهایی به " +"تنهایی آموزش دهد. هر تغییر پیشنهادی را به یک نتیجه مشاهده شده و تصمیم بعدی " +"مرتبط می کند. حفظ تغییرات بی اثر نیز مهم است: آنها به عامل بعدی می گویند که " +"کدام فرضیه قبلاً در آن زمینه آزمایش شده است." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}من می‌خواهم مدل یاد بگیرد که چگونه از بازخورد استفاده کند.{ph1} یک " +"نتیجه خنثی دلیلی برای تجدید نظر در تغییر است. تغییر عدم تطابق ممکن است به " +"دلیل دیگری اشاره کند. وقتی ویرایش‌های محلی آموزنده نیستند، عامل باید بتواند " +"بازنمایی منبع را بازبینی کند یا شواهد را دوباره بررسی کند." + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"یادگیری انجام آن انتخاب ها مستلزم استقلال است. گاهی اوقات گام بعدی مفید، " +"بررسی تماس گیرنده دیگر به جای کامپایل ویرایش دیگری است. یک توالی سفت و سخت " +"از بازنویسی های مورد نیاز این انتخاب را حذف می کند، همراه با بخشی از رفتاری " +"که می خواهیم مدل یاد بگیرد." + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "چرا مهندسی معکوس برای یادگیری تقویتی جالب است" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"بازسازی با دامنه مشخص محیطی عملی برای مطالعه این تصمیم‌ها فراهم می‌کند. با " +"ثابت نگه داشتن نسخه هدف و کامپایلر، بسیاری از آزمایش‌های کد منبع بازخورد " +"سریع و تکرارپذیر می‌دهند. عامل می‌تواند کد پیشنهادی را کامپایل کند، تفاوت‌ها" +" را بررسی کند و گام بعدی را انتخاب کند." + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"یادگیری تقویتی می تواند این فرآیند تصمیم گیری را از طریق بازخوردی که دریافت " +"می کند آموزش دهد. یک نامزد پذیرفته شده توسط یک چک تعریف شده یک نتیجه مشخص به" +" ما می دهد، در حالی که توالی تلاش ها به ما امکان می دهد مشاهده کنیم که چقدر " +"کار برای رسیدن به آن لازم است." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"در حال حاضر تحقیقاتی وجود دارد که از این جهت حمایت می کند. " +"{ph0}LLM4Decompile{ph1} مدل های تخصصی برای دیکامپایل را مطالعه می کند. " +"{ph2}AutoDecompiler{ph3} با استفاده از بازخورد کامپایلر و اجرا، اصلاح چند " +"نوبتی را آموزش می‌دهد. مطالعات آنها بر بازیابی عملکردی متمرکز است. برای این " +"کار، من از آنها به عنوان نقطه شروع برای کار مرتبط یافتن منبعی که با خروجی یک" +" کامپایلر تاریخی مطابقت دارد استفاده می کنم." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"با این حال، برای رسیدن به چنین وظیفه ای به خوبی تعریف شده، ممکن است ابتدا " +"نیاز داشته باشیم که یک تابع دارای چه منابعی است یا یک روش جدید برای مشاهده " +"رفتار برنامه هنگام اجرا را طراحی کنیم. به عنوان مثال، در TH08، یک {ph0}تفاوت" +" برخورد منجر به نحوه مدیریت برنامه اصلی با محاسبات ممیز شناور شد{ph1}. قبل " +"از اینکه عامل بتواند یک تصحیح مفید را آزمایش کند، باید تعیین می کرد که چه " +"چیزی را باید اندازه گیری کند." + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "" +"این یک نقش دیگر را برای یک مدل به طور گسترده نشان می دهد: کمک به قابل بررسی " +"کردن مشکل در وهله اول. هنگامی که آن چک وجود داشت، می‌توانیم بررسی کنیم که یک" +" خط‌مشی جستجوی آموخته شده تا چه حد می‌تواند با آن برسد." + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "هنگامی که بررسی کننده تأیید اشتباه است" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"وقتی یک بررسی را برای آموزش به کار می‌بریم، دامنه آن هم بخشی از محیط یادگیری" +" می‌شود. من چنین مرجع یا ابزار بررسی را اوراکل می‌نامم. حتی پاسخ تکرارپذیر " +"را باید در محدوده چیزی فهمید که واقعاً بررسی می‌کند." + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"TH08 نشان داد که مشکلات می‌توانند بیرون از دامنه بررسی پنهان بمانند. بعضی " +"توابع بازسازی‌شده با وجود ثابت‌های ممیز شناور اشتباه، مقایسه دقیق را قبول " +"شدند. مقایسه‌کننده پیش از بررسی دستورها آدرس‌های جابه‌جا‌شده را تنظیم " +"می‌کرد، اما مقدار اشاره‌شده را فقط وقتی بررسی می‌کرد که برای اعتبارسنجی " +"صریحاً ثبت شده بود. ارجاع‌های دیگر به ثابت‌ها می‌توانستند بدون بررسی مقدار " +"قبول شوند." + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"برای رفع این شکاف، یک {ph0}ممیزی گسترده‌تر{ph1} ثابت‌های نادرستی را در " +"توابعی که قبلاً تأیید شده بودند پیدا کرد. در یک محاسبه، کد منبع بازسازی شده " +"{ph2} را اضافه کرد، در حالی که کد اصلی {ph3} را اضافه کرد." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}مدلی که توسط چک راستی‌آزمایی قدیمی پاداش می‌گیرد، می‌تواند یاد بگیرد که" +" یک بازسازی نادرست ایجاد کند.{ph1} ما یک مدل RL را با استفاده از آن " +"بررسی‌کننده آموزش ندادیم. نقصی که مشاهده کردیم در خود چک بود. اما اگر از آن " +"به عنوان پاداش استفاده می کردیم، همان نقطه کور بخشی از محیط آموزشی می شد." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"یک تست عملکردی می تواند نقطه کور مشابهی داشته باشد. {ph0}تحقیق با استفاده از" +" fuzzing دیفرانسیل در دیکامپایلرهای LLM{ph1} تفاوت‌های رفتاری را خارج از " +"آزمون‌های ارائه شده یافت. بنابراین ما باید یک آزمون قبولی را بر حسب مواردی " +"که انجام می دهد درک کنیم. به طور مشابه، یک تطابق دستورالعمل باید از نظر بایت" +" ها و داده هایی که تأیید می کند درک شود." + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"قبل از استفاده از هر نوع بررسی تأیید به عنوان پاداش، آن را با نتایج عمداً " +"نادرست آزمایش می‌کنم. من همچنین پذیرش نهایی را از کد منبعی که عامل هوش " +"مصنوعی می تواند ویرایش کند جدا نگه می دارم. مدل باید با بازسازی صحیح برنامه،" +" تأیید صحت داشته باشد. در غیر این صورت، کپی کردن یک آرایه بایتی از هدف می " +"تواند یک سیستم امتیازدهی ساده لوح را بدون بازیابی کد منبع مفید فریب دهد." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "" +"{ph0}بهبود یادگیرنده و بهبود بررسی‌کننده تأیید آن مربوط به یک مسئله تحقیقاتی" +" است.{ph1} همانطور که یادگیرنده در بهینه‌سازی بازخوردی که ما به آن می‌دهیم " +"بهتر می‌شود، درک آن بازخورد نیز مهم‌تر می‌شود." + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "مقایسه ای که ارزش اجرا دارد" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"با انجام این بررسی‌ها، مقایسه را روی یک خانواده کار ثابت VC7.1 شروع می‌کنم. " +"اول، من خطوط پایه را برای یک مدل هوش مصنوعی همه منظوره قوی و یک مدل کوچکتر " +"ایجاد می کنم. افزودن دانش مخزن به مدل کوچکتر، تغییرات بازیابی را نشان می " +"دهد. از آنجا، تخصص تحت نظارت و یک نسخه آموزش داده شده RL به ما اجازه می دهد " +"بررسی کنیم که آموزش چه چیزی را اضافه می کند." + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"برای اینکه این مقایسه ها آموزنده باشد، هر مدل شواهد و ابزارهای هدف یکسانی را" +" دریافت می کند. برای مقایسه‌های آموزشی خاص، مدل پایه و دانش موجود را نیز " +"ثابت نگه می‌دارم. آزمایش‌های مکرر به تمایز یک استراتژی جستجوی قابل اعتماد از" +" راه‌حل نامزدی که به طور تصادفی موفق می‌شود کمک می‌کند." + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"سپس دو شرط شروع را جدا می‌کنم: بازسازی یک تابع از دستورالعمل‌های آن، و بستن " +"چند تفاوت آخر در منبع حفظ شده. یک مدل هوش مصنوعی تخصصی ممکن است در کار دوم " +"عالی باشد در حالی که یک مدل هوش مصنوعی همه منظوره بسیاری از کارهای مورد نیاز" +" برای رسیدن به آن را انجام می دهد. اندازه گیری آنها به طور جداگانه این تقسیم" +" کار را آشکار می کند." + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"هر دو کار به نمونه‌های آزمایشی نیاز دارند که از آموزش و بازیابی حذف شوند. کد" +" موتور اشتراک گذاری بازی های مرتبط Touhou. حذف یک بازی از تمرین همچنان می " +"تواند عملکردهای تقریباً یکسانی را در مجموعه تمرینی باقی بگذارد. در عوض، من " +"کل گروه‌های کد منبع مرتبط را حذف می‌کنم و پاسخ‌های تأیید شده‌شان را هم از " +"داده‌های آموزشی و هم از کتابخانه بازیابی خارج می‌کنم." + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"برای این مثال‌ها، نتیجه، مطابقت‌های کامل و تأیید شده مستقل خواهد بود. " +"بودجه‌های برابر برای پیشنهادهای نامزد یا تلاش‌های کامپایل به مقایسه کیفیت " +"جستجو کمک می‌کند. اندازه‌گیری زمان و هزینه کل، از جمله کامپایل، نشان می‌دهد " +"که آیا این کیفیت گردش کار کارآمدی ایجاد می‌کند یا خیر. هزینه های آموزشی باید" +" جداگانه اندازه گیری شود." + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"هر دو اندازه گیری مهم است. یک پروپوزال ارزان می‌تواند منجر به گردش کار " +"گران‌قیمتی شود اگر باعث کامپایل‌های بیشتری شود که اطلاعات مفیدی ارائه " +"نمی‌کند. برعکس، یک مدل کندتر ممکن است اقتصادی تر باشد اگر آزمایش مفیدی را " +"زودتر پیدا کند. مقایسه باید شامل این هزینه ها باشد." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"شمارش نتایج پذیرفته شده همچنین پیشرفت متوسط را در چشم انداز نگه می دارد. یک " +"TH09 {ph0}replay-save نامزد{ph1} امیدوارکننده به نظر می‌رسید، زیرا تابع " +"کامپایل‌شده اندازه مورد انتظار را داشت، اما یک مقایسه کامل همچنان تفاوت‌های " +"اساسی را پیدا کرد. تغییرات در نحوه چیدمان دستورالعمل ها توسط کامپایلر می " +"تواند بدون حل مشکل اساسی، نامزد را نزدیک تر کند. چنین تشخیص‌هایی می‌توانند " +"آزمایش بعدی را راهنمایی کنند، اما من هر پاداشی را برای «نزدیک‌تر شدن» در " +"برابر بررسی پذیرش کامل تأیید می‌کنم." + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"من به الگوی این نتایج علاقه مند هستم. اگر یک مدل تخصصی هوش مصنوعی در یک " +"خانواده کامپایلر آشنا به خوبی عمل کند، آیا این مزیت از تغییر زنجیره ابزار " +"باقی می ماند؟ و هنگامی که هر دو مدل هوش مصنوعی بازیابی خوبی داشته باشند، " +"آموزش هنوز چقدر اضافه می کند؟ پاسخ‌ها به ما کمک می‌کنند تصمیم بگیریم که هر " +"نوع مدل در کجا مفیدتر است." + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "این چه نوع عامل هوش مصنوعی را پیشنهاد می کند؟" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"اگر مدل ها در مراحل مختلف کمک کننده باشند، یک ترتیب مفید ممکن است عاملی " +"گسترده با دسترسی به یک مدل تخصصی هوش مصنوعی باشد. هنگامی که یک کار به یک " +"جستجوی کامپایلر آشنا تبدیل می شود، می تواند مدل تخصصی هوش مصنوعی را برای " +"نامزدها بپرسد. اگر نتایج منطقی نباشند، عامل گسترده‌تر می‌تواند به شواهد هدف " +"بازگردد یا خود اندازه‌گیری را بررسی کند." + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "" +"در آن ترتیب، تخصص به ابزاری تبدیل می‌شود که عامل می‌تواند با توسعه تحقیقات " +"انتخاب کند. عامل آزادی تغییر جهتی را حفظ می کند که پیشرفت های قبلی را ممکن " +"کرده است." + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"این به طور طبیعی از تغییر صنعتی که در مقاله قبلی توضیح دادم ناشی می شود. " +"توانایی انجام آزمایش‌های بسیار بیشتر، نحوه سازماندهی کار را تغییر می‌دهد. " +"همچنین دلیلی به ما می دهد تا بپرسیم کدام تصمیمات نیاز به قضاوت گسترده دارند " +"و کدام یک از طریق تجربه مکرر با یک هنر خاص بهبود می یابند." + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"تا اینجا قوی‌ترین مدل عمومی جای خود را در گردش کار من پیدا کرده، چون مسائلی " +"را حل کرده که قبلاً حل نشده مانده بودند. همین موفقیت‌ها مرا به بررسی دقیق‌تر" +" فرایند ترغیب می‌کنند: چه مقدار به گستردگی توانایی مدل وابسته بود، و چه " +"مقدار را مدلی آموزش‌دیده برای همین نوع بازسازی می‌تواند انجام دهد؟" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "" +"{ph0}مخزن‌ها راهی برای آزمایش سؤال به ما می‌دهند.{ph1} من می‌خواهم از آن " +"رکورد برای ساخت مقایسه و دیدن آنچه یاد می‌گیریم استفاده کنم." + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "مدارک و اسناد مدل" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"مثال‌ها مقایسه‌های سطح عملکرد تاریخی ثبت شده در commit‌های مرتبط را توصیف " +"می‌کنند. بررسی های زمان اجرای کل بازی نقاط عطف جداگانه ای هستند. منبع و " +"سوابق مطابق در 13 اکتبر 2026 بررسی شدند." + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"برچسب TH09 {ph0} به معنای GPT-6-Astra است. مدل مرتبط با {ph1} در طول زمان " +"تغییر کرد، به طوری که برچسب به تنهایی نمی تواند مدل مورد استفاده در یک اجرای" +" خاص را شناسایی کند. نام مدل صریح در سایر کامیت‌های ذکرشده، انتساب ثبت شده " +"را ارائه می کند. این تاریخچه ها شامل اندازه گیری ثابت هزینه یا تلاش برای هر " +"اجرا نمی شود." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "" +"{ph0}TH09 طول عمر اشیای موقت:{ph1} {ph2}بررسی زمینه اولیه{ph3} و " +"{ph4}بازسازی کامل تأیید شده توسط یک کامپایل مجدد تمیز از منبع{ph5}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"{ph0}TH09 Front پاسخ به تماس:{ph1} {ph2}مناطق تشخیصی که مطابقت نداشتند{ph3}،" +" نمودار جریان کنترل جدید {ph4}Astra{ph5} و {ph6}بررسی مجدد پذیرفته شده " +"آن{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}دانش کامپایلر:{ph1} {ph2}استفاده دوباره از رفتار دسته‌بندی شناسه‌ها در " +"TH095{ph3}، {ph4}کد منبع بازیکن TH04 و ترتیب لینک{ph5} و {ph6}بازسازی کامل " +"تابع ایجاد دشمن TH09 توسط Luna{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}بررسی و تشخیص:{ph1} {ph2}TH08 ممیزی ثابت ممیز شناور{ph3}، {ph4}TH08 " +"بررسی عددی{ph5} و {ph6}TH09 بازسازی صرفه جویی در پخش{ph7}." + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "" +"مقایسه‌های پیشنهادی مدل‌های تخصصی و آموزش RL آزمایش‌های آینده هستند. تاریخچه" +" پروژه به آنها انگیزه می دهد. هیچ مدل تخصصی آموزش دیده ای برای این مقاله " +"ارزیابی نشد." + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "آیا مهندسی معکوس به مدل بزرگتری نیاز دارد؟ | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "" +"آنچه که بازسازی Touhou در مورد مدل های عمومی، مدل های تخصصی و یادگیری ارائه " +"فرضیه های بهتر از بازخورد کامپایلر به من آموخت." + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "در این صفحه" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "مدل ها و مقاله مهندسی معکوس" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "آزمایش های بازسازی منتخب" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "بازگشت به بالا" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "" +"{ph0}یادداشت‌های تفصیلی شواهد{ph1} شامل مقایسه‌های ثبت‌شده و زمینه آزمایش‌ها" +" هستند." + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "نویسنده: N0zoM1z0 · ۱۳ اکتبر ۲۰۲۶ · پیش‌نویس برای بازبینی" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "راهنمای نصب" diff --git a/website/locales/fr/messages.po b/website/locales/fr/messages.po index f6e6ab357..1664f4bd5 100644 --- a/website/locales/fr/messages.po +++ b/website/locales/fr/messages.po @@ -32,18 +32,18 @@ msgid "Thoughts on reverse engineering." msgstr "Réflexions sur l'ingénierie inverse." #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "Reconstruction du jeu{ph0}Essai" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "La révolution industrielle dans l'ingénierie inverse" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " @@ -53,19 +53,20 @@ msgstr "" "TH04 m'ont appris sur les agents, la vérification et les connaissances qui " "se combinent dans les projets." -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "Lire l'article" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "Par N0zoM1z0 · 10 octobre 2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -101,6 +102,8 @@ msgstr "" " avec REA et les agents d'IA." #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -137,6 +140,7 @@ msgstr "" "agent de codage." #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -157,6 +161,7 @@ msgid "REA home" msgstr "Accueil REA" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -177,6 +182,7 @@ msgid "Main navigation" msgstr "Navigation principale" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -197,6 +203,7 @@ msgid "REA on GitHub" msgstr "REA sur GitHub" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -217,6 +224,7 @@ msgid "Join REA on Discord" msgstr "Rejoindre REA sur Discord" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -236,7 +244,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "Suivre REA sur X" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "Haut de page" @@ -11775,6 +11783,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "Même espacement: 256 ÷ 16 = 16 unités d'angle = 22,5°" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -11795,6 +11804,7 @@ msgid "Showcases" msgstr "Études de cas" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -11815,6 +11825,7 @@ msgid "Blog" msgstr "Blog" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -11835,6 +11846,7 @@ msgid "Get started" msgstr "Démarrer" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -11854,7 +11866,8 @@ msgctxt "shared" msgid "Guides" msgstr "Guides" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -11874,7 +11887,8 @@ msgctxt "shared" msgid "Source" msgstr "Code source" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -11894,7 +11908,8 @@ msgctxt "shared" msgid "MIT license" msgstr "Licence MIT" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -11914,7 +11929,8 @@ msgctxt "shared" msgid "Join the community" msgstr "Rejoindre la communauté" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -12885,6 +12901,1417 @@ msgstr "" "connectez le serveur MCP d’Everywhere pour inspecter le trafic capturé avec " "votre agent." +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "Modèles spécialisés{ph0}Essai" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "Le reverse engineering a-t-il besoin d’un modèle plus grand ?" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "" +"Ce que la reconstruction de Touhou suggère sur les modèles généralistes, les" +" modèles spécialisés et l’apprentissage à partir des retours du compilateur." + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Par N0zoM1z0 · 13 octobre 2026" + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "Aller au contenu" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "{ph0}Accueil{ph1} / {ph2}Blog{ph3} / Modèles et rétro-ingénierie" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "Essai" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "L'ingénierie inverse nécessite-t-elle un modèle plus grand ?" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Par N0zoM1z0 · 13 octobre 2026" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "À retenir" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "" +"{ph0}La capacité du modèle affecte les hypothèses qu'un agent d'IA peut " +"proposer.{ph1} Les sessions ultérieures ont résolu des problèmes que les " +"travaux antérieurs n'avaient pas résolus." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "" +"{ph0}Un compilateur familier propose des modèles concrets à apprendre pour " +"un modèle spécialisé.{ph1} Certaines correspondances exactes de code machine" +" dépendent de modèles de code source spécifiques et réutilisables." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "" +"{ph0}Incluez les connaissances du référentiel dans une comparaison " +"équitable.{ph1} Un modèle plus petit avec une bonne récupération des " +"connaissances peut déjà contenir suffisamment d'informations pour " +"progresser." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "" +"{ph0}Entraînez le modèle à choisir la prochaine expérience utile et testez " +"son vérificateur.{ph1} Les retours ne sont utiles que dans la mesure où le " +"vérificateur vérifie les bonnes choses." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "" +"{ph0}Évaluez les résultats de reconstruction vérifiés en fonction du temps " +"et du coût.{ph1} C'est ce que je souhaite mesurer pour le flux de travail " +"complet de l'agent IA." + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "Dans cet article" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}Ce que les modèles plus performants ont changé{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}Pourquoi se spécialiser ?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}Où cette expérience doit-elle être stockée ?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}Apprendre la prochaine expérience utile{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}Ingénierie inverse et apprentissage par renforcement{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}Lorsque le vérificateur est erroné{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}Une comparaison qui vaut la peine d'être menée{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}Quel type d’agent IA cela suggère-t-il ?{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "Ce que les modèles plus performants ont changé" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"Depuis août 2026, j'explore combien de rétro-ingénierie un agent peut " +"effectuer avec accès à un programme et un moyen de vérifier son travail. La " +"majeure partie de mon expérience vient de la reconstruction de jeux, en " +"particulier Touhou. Au fur et à mesure que j'ai changé de modèle, les " +"référentiels ont conservé une trace de ce que chaque session a réussi à " +"récupérer." + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"Une grande partie du travail vise une reconstruction exacte : nous compilons" +" le code maintenu avec une chaîne d'outils de l'époque dont les versions " +"sont fixées, puis vérifions si elle reproduit la fonction cible. Quand un " +"modèle ultérieur débloque le travail, les changements du code permettent de " +"comprendre ce qui a rendu ce progrès possible." + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "" +"Les variables temporaires nécessitaient des durées de vie qui se " +"chevauchaient" + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"Une grande partie de la logique d'une fonction d'attaque TH09 avait déjà été" +" reconstruite, mais le compilateur stockait toujours les résultats " +"temporaires différemment de l'original. Le problème restant était de savoir " +"combien de temps ces résultats devaient rester en vie et quand leur stockage" +" pouvait être réutilisé." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"Un {ph0}GPT-6-Sol enregistrement de session{ph1} a signalé cette incohérence" +" après avoir testé plusieurs arrangements de code source ordinaires. Lorsque" +" {ph2}GPT-6.1-Sol a réexaminé le problème{ph3}, il a proposé une hypothèse " +"utile sur la durée de vie de ces variables temporaires." + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"La fonction produisait des résultats temporaires et les copiait dans des " +"positions d'animation. En C++, un résultat temporaire reste actif jusqu'à la" +" fin de l'expression qui l'utilise. Le regroupement des opérations réelles " +"en une seule expression permettait de conserver ces résultats ensemble, de " +"sorte que le compilateur ne pouvait plus réutiliser le même stockage pour " +"chacun d'entre eux." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"Un résultat partageait encore son espace de stockage avec une valeur " +"utilisée plus tard pour les collisions. Donner à cette valeur une durée de " +"vie distincte a éliminé le dernier chevauchement. Après plusieurs " +"expériences ciblées, {ph0}une recompilation propre a confirmé que la " +"fonction entière correspondait à l'original{ph1}." + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"Je suis intéressé par la façon dont la découverte et les tests se sont " +"soutenus mutuellement. L’hypothèse sur la durée de vie des objets " +"temporaires a donné une nouvelle direction à l’agent IA. Les retours du " +"compilateur l'ont aidé à affiner cette hypothèse en un arrangement de code " +"source correspondant." + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "Un graphique de flux de contrôle différent" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"Une deuxième fonction TH09 montre pourquoi cette nouvelle direction peut " +"être importante. Ici, l'obstacle était la façon dont plusieurs branches " +"partageaient leur travail final. Les travaux antérieurs de " +"{ph0}GPT-6.1-Sol{ph1} ont permis de faire correspondre certaines parties de " +"la fonction, mais les branches se sont toujours jointes différemment de " +"l'original." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}GPT-6-Astra a modifié le graphique de flux de contrôle " +"environnant{ph1}. Les chemins principaux menaient désormais à une mise à " +"jour finale et à un retour partagés. Dans cette structure source, le " +"compilateur combinait les branches de la même manière que l'original. La " +"fonction complète correspondait et une {ph2}vérification de reconstruction " +"distincte l'a confirmée{ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}Changer la représentation a ouvert un espace de recherche plus " +"productif.{ph1} Les deux cas me donnent une raison de prendre au sérieux la " +"capacité générale du modèle : un agent peut continuer à essayer des " +"variantes locales pendant longtemps avant de trouver une meilleure façon " +"d'exprimer le travail environnant." + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"Les sessions ultérieures ont aussi hérité du code précédent et des échecs " +"documentés. Ce travail accumulé faisait partie de leur avantage. " +"L'historique permet d'examiner les découvertes et leurs vérifications ; une " +"comparaison contrôlée aiderait à séparer l'effet du modèle de celui de " +"l'expérience héritée." + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"C'est ce qui rend la question intéressante pour moi. Certains progrès sont " +"venus de la recherche d'une nouvelle représentation. Une grande partie du " +"travail restant consistait à tester différentes dispositions de code source " +"par rapport à un compilateur familier. Dans quelle mesure cela nécessite-t-" +"il une grande capacité de raisonnement ? Combien un modèle pourrait-il " +"apprendre en travaillant de manière répétée avec ce compilateur et ce code ?" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "" +"Pourquoi un modèle d’IA spécialisé pourrait-il fonctionner correctement ?" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"Touhou nous donne une raison concrète d'attendre que cette expérience nous " +"aide. Une grande partie du code du jeu provient du même auteur, ZUN, les " +"habitudes récurrentes constituent donc une hypothèse de départ raisonnable. " +"Les référentiels confirment cela avec des exemples utiles : les boucles " +"associées et les arrangements d'assistance ont fourni des hypothèses à " +"travers les jeux." + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "" +"Ces modèles de source deviennent plus spécifiques lorsque nous incluons le " +"compilateur. Sous une version et un ensemble d'options particuliers, de " +"petites modifications dans la source peuvent produire des différences " +"reproductibles dans le code machine. Certaines de ces différences sont " +"étonnamment obscures." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"Dans TH095, par exemple, {ph0}même le nom d'une variable locale peut " +"affecter l'endroit où VC7.1 la stocke{ph1}. Le déplacement de sa déclaration" +" n'a pas résolu la configuration du stockage. Cependant, une fonction " +"d'arrière-plan antérieure avait révélé un modèle de dénomination qui " +"affectait le choix du compilateur. Cela suggère une hypothèse plus " +"prometteuse pour {ph2}reconstruire {ph3}{ph4}." + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "" +"La réutilisation de ce modèle pour la variable de taille de fichier a " +"produit la mise en page requise sans ajouter de stockage. La fonction " +"complète correspondait alors." + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "" +"Il s’agit d’un détail très spécifique qu’un modèle d’IA à usage général peut" +" ne pas connaître lorsqu’il rencontre le problème pour la première fois. Un " +"modèle spécialisé pour ce compilateur pourrait détecter de nombreux cas de " +"ce type et découvrir quelles variantes du code source méritent d'être " +"testées en premier." + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"L’opportunité est particulièrement évidente dans les problèmes d’appariement" +" final dont nous comprenons déjà le comportement. Nous nous demandons alors " +"quel arrangement de code source ordinaire ce compilateur transforme en " +"instructions observées. La spécialisation pourrait aider le modèle à " +"proposer ces formes plus efficacement, tandis que la cible détermine " +"toujours quelles hypothèses survivent." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"Les modèles utiles doivent conserver leur contexte. TH08 utilise une version" +" Visual C++ antérieure à TH095 et TH09. TH04 utilise un compilateur " +"différent de l'ère DOS. Sa {ph0}reconstruction du code du joueur{ph1} " +"nécessitait différentes hypothèses sur les modèles de code source et sur la " +"manière dont le code compilé était lié à un exécutable. Avoir le même auteur" +" nous donne une attente initiale, mais chaque cible nous dit si elle " +"s'applique. Un modèle spécialisé devrait distinguer ces contextes." + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "Où cette expérience doit-elle être stockée ?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"Avant de décider d'enseigner ces modèles via la formation de modèles, " +"j'examinerais les connaissances que nous conservons déjà dans le " +"référentiel. Dans l'{ph0}essai précédent{ph1}, j'ai écrit qu'il deviendrait " +"la mémoire de travail du projet. Cette mémoire comprend les leçons du " +"compilateur, ainsi que la source et les expériences ratées qui les ont " +"rendues utiles." + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"En récupérant cet enregistrement, un agent peut partir d’un résultat connu " +"et inspecter comment nous l’avons atteint. Cela peut également éviter des " +"alternatives qui ont déjà échoué dans le même contexte. Le point de départ " +"s'améliore sans modifier les paramètres entraînés du modèle." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"Lors de la reconstruction de la fonction de TH09 pour créer des ennemis, une" +" {ph0}session GPT-6-Luna-max{ph1} a pris une hypothèse à partir du code " +"source TH08 associé. Ce code précédent suggérait comment organiser la boucle" +" et gérer les échecs à l'intérieur. Le propre témoignage de TH09 a fourni " +"des détails spécifiques au jeu. Les reconstructions à partir des sources ont" +" confirmé que la fonction complète correspondait." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}\"Le modèle ne connaissait pas cette bizarrerie du compilateur\" et " +"\"le modèle n'a pas pu l'utiliser\" sont des problèmes différents.{ph1} La " +"récupération peut résoudre le premier, mais transformer ce fait en un " +"candidat utile demande encore du travail. Et si le code source candidat " +"échoue, le modèle doit décider de la signification du résultat pour sa " +"prochaine tentative. Connaître le modèle pertinent n’est que le début de ce " +"processus." + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"Pour cette raison, j’inclurais un modèle d’IA à usage général plus petit " +"avec une bonne récupération dans toute comparaison. Lui donner la même " +"bibliothèque d'expériences nous aiderait à identifier ce que la formation " +"ajoute : une meilleure génération de candidats, de meilleures décisions " +"après feedback, ou les deux." + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "Apprendre la prochaine expérience utile" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"Ces décisions après retour d’information sont ce que j’aimerais le plus " +"étudier. En reconstruction agentique, le modèle propose une explication et " +"la teste par rapport au programme. Même lorsque le code source candidat " +"échoue, le résultat peut réduire les possibilités restantes et suggérer une " +"prochaine expérience plus utile." + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "" +"Prenons à nouveau l'exemple des résultats temporaires. Sa source finale " +"montre l'arrangement qui a fonctionné, mais l'itinéraire vers cette source " +"contient plus d'informations. Chacune des expériences suivantes a permis " +"d’identifier ce qui devait encore changer." + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "Expérimenter" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "Ce que son résultat nous a appris" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "Essayez une autre façon de copier les résultats" + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "Le code de copie change, mais la fonction diffère toujours." + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "Utiliser directement les valeurs renvoyées" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "" +"La copie suit le modèle d'origine, mais le stockage temporaire diffère " +"toujours." + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "Gardez toutes les variables temporaires valides en même temps" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "" +"Ils bénéficient d'un stockage séparé, mais l'un d'entre eux chevauche " +"toujours une valeur utilisée ultérieurement pour les contrôles de collision." + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "Gardez la valeur de contrôle de collision séparée" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "" +"Une recompilation propre à partir de la source confirme la correspondance " +"complète." + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "" +"Expériences sélectionnées de la reconstruction de la fonction d'attaque ci-" +"dessus, regroupées selon ce qu'elles nous ont appris." + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"Un dossier de formation qui conserve cette séquence peut enseigner plus que " +"la seule source finale. Il relie chaque changement proposé à un résultat " +"observé et à la décision suivante. Conserver des variantes inefficaces est " +"également important : elles indiquent à un agent ultérieur quelles " +"hypothèses ont déjà été testées dans ce contexte." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}Je voudrais que le modèle apprenne à utiliser les retours.{ph1} Un " +"résultat neutre est une raison pour reconsidérer la variation ; une " +"inadéquation modifiée peut indiquer une autre cause. Lorsque les " +"modifications locales cessent d’être informatives, l’agent doit être en " +"mesure de revoir la représentation source ou d’inspecter à nouveau les " +"preuves." + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"Apprendre à faire ces choix nécessite de l’autonomie. Parfois, l'étape " +"suivante utile consiste à inspecter un autre appelant plutôt que de compiler" +" une autre modification. Une séquence rigide de réécritures requises " +"supprimerait ce choix, ainsi qu'une partie du comportement que nous " +"souhaitons que le modèle apprenne." + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "" +"Pourquoi l'ingénierie inverse est intéressante pour l'apprentissage par " +"renforcement" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"La reconstruction limitée nous offre un environnement pratique pour étudier " +"ces choix. Une fois les versions de la cible et du compilateur fixées, de " +"nombreuses expériences sources produisent des retours rapides et " +"reproductibles. L'agent peut compiler un candidat, inspecter l'inadéquation " +"et utiliser cette observation pour choisir la prochaine étape." + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"L'apprentissage par renforcement pourrait entraîner ce processus de prise de" +" décision grâce aux retours qu'il reçoit. Un candidat accepté par un " +"contrôle défini nous donne un résultat concret, tandis que la séquence des " +"tentatives nous permet d'observer combien de travail il a fallu pour y " +"parvenir." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"Il existe déjà des recherches soutenant cette direction. " +"{ph0}LLM4Decompile{ph1} étudie les modèles spécialisés pour la " +"décompilation. {ph2}AutoDecompiler{ph3} entraîne le raffinement multi-tours " +"à l'aide des retours du compilateur et de l'exécution. Leurs études portent " +"sur la restauration du comportement. Pour ce travail, je les utiliserais " +"comme point de départ pour la tâche connexe consistant à trouver du code " +"source qui correspond à la sortie d'un compilateur historique." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"Cependant, pour atteindre une tâche aussi bien définie, nous devrons peut-" +"être d’abord établir quelles ressources possède une fonction ou concevoir " +"une nouvelle manière d’observer le comportement du programme pendant son " +"exécution. Dans TH08, par exemple, une {ph0}différence de collision a " +"conduit à la manière dont le programme d'origine gérait les calculs à " +"virgule flottante{ph1}. Avant que l’agent puisse tester une correction " +"utile, il devait déterminer quoi mesurer." + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "" +"Cela suggère un autre rôle pour un modèle largement performant : contribuer " +"à rendre le problème vérifiable en premier lieu. Une fois que cette " +"vérification existe, nous pouvons étudier jusqu’où une politique de " +"recherche apprise peut aller avec elle." + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "Lorsque le vérificateur est erroné" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"Dès qu'une vérification sert à l'entraînement, sa couverture fait partie de " +"l'environnement d'apprentissage. J'appelle oracle cette référence ou ce " +"vérificateur. Même une réponse reproductible doit être comprise à partir de " +"ce qu'elle vérifie réellement." + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"TH08 a montré tout ce qui peut se cacher en dehors de cette couverture. " +"Certaines fonctions reconstruites ont réussi leurs comparaisons exactes avec" +" de mauvaises constantes flottantes. Le comparateur a ajusté les adresses " +"déplacées avant de vérifier les instructions, mais il a vérifié les valeurs " +"derrière ces adresses uniquement lorsqu'elles avaient été explicitement " +"enregistrées pour vérification. D'autres références littérales pourraient " +"passer sans que leurs valeurs soient examinées." + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"Pour combler cette lacune, un {ph0}audit plus large{ph1} a détecté des " +"constantes incorrectes dans les fonctions qui avaient déjà réussi la " +"vérification. Dans un calcul, le code source reconstruit a ajouté {ph2}, " +"tandis que l'original a ajouté {ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}Un modèle récompensé par l'ancien contrôle de vérification pourrait " +"apprendre à produire une reconstruction incorrecte.{ph1} Nous n'avons pas " +"entraîné de modèle RL à l'aide de ce vérificateur. L’échec que nous avons " +"constaté concernait le contrôle lui-même. Mais si nous l’utilisions comme " +"récompense, le même angle mort deviendrait partie intégrante de " +"l’environnement d’apprentissage." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"Un test fonctionnel peut avoir un angle mort similaire. {ph0}Des recherches " +"utilisant le fuzzing différentiel sur les décompilateurs LLM{ph1} ont révélé" +" des différences de comportement en dehors des tests fournis. Il faut donc " +"comprendre une épreuve de réussite en fonction des cas qu'elle exerce. De " +"même, une correspondance d’instructions doit être comprise en termes " +"d’octets et de données qu’elle vérifie." + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"Avant d’utiliser l’un ou l’autre type de contrôle de vérification comme " +"récompense, je le testerais avec des résultats délibérément incorrects. Je " +"garderais également l'acceptation finale séparée du code source que l'agent " +"IA peut modifier. Le modèle doit réussir la vérification en reconstruisant " +"correctement le programme. Sinon, la simple copie d'un tableau d'octets à " +"partir de la cible pourrait tromper un système de notation naïf sans " +"récupérer le code source utile." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "" +"{ph0}Améliorer le modèle et améliorer son vérificateur relèvent du même " +"problème de recherche.{ph1} Plus le modèle sait optimiser le retour que nous" +" lui donnons, plus il devient important de comprendre ce retour." + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "Une comparaison qui vaut la peine d'être menée" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"Une fois ces contrôles en place, je commencerais la comparaison sur une " +"famille de tâches VC7.1 fixe. Premièrement, j’établirais les bases d’un " +"modèle d’IA à usage général solide et d’un modèle plus petit. L'ajout de " +"connaissances sur le référentiel au modèle plus petit montrerait les " +"changements apportés à la récupération. À partir de là, une spécialisation " +"supervisée et une version formée par RL nous permettraient d'examiner ce que" +" la formation ajoute." + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"Pour rendre ces comparaisons informatives, chaque modèle recevrait les mêmes" +" preuves et outils cibles. Pour les comparaisons spécifiques à la formation," +" je conserverais également le modèle de base et les connaissances " +"disponibles fixes. Des essais répétés permettraient de distinguer une " +"stratégie de recherche fiable d'une solution candidate qui réussit par " +"hasard." + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"Je séparerais alors deux conditions de départ : reconstruire une fonction à " +"partir de ses instructions, et fermer les dernières différences dans le " +"source maintenu. Un modèle d’IA spécialisé peut être excellent pour la " +"deuxième tâche, tandis qu’un modèle d’IA à usage général effectue une grande" +" partie du travail nécessaire pour y parvenir. Les mesurer séparément " +"révélerait cette division du travail." + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"Les deux tâches nécessitent des exemples de test exclus de la formation et " +"de la récupération. Les jeux Touhou associés partagent le code moteur. " +"L'exclusion d'un jeu de l'entraînement pourrait néanmoins laisser des " +"fonctions presque identiques dans l'ensemble d'entraînement. Au lieu de " +"cela, j'exclurais des groupes entiers de code source associé et garderais " +"leurs réponses vérifiées hors des données de formation et de la bibliothèque" +" de récupération." + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"Pour ces exemples, le résultat serait des correspondances complètes et " +"vérifiées de manière indépendante. Des budgets égaux pour les propositions " +"de candidats ou les tentatives de compilation aideraient à comparer la " +"qualité de la recherche. Mesurer le temps et le coût totaux, y compris la " +"compilation, montrerait si cette qualité produit un flux de travail " +"efficace. Les coûts de formation doivent être mesurés séparément." + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"Les deux mesures comptent. Une proposition bon marché peut conduire à un " +"flux de travail coûteux si elle entraîne davantage de compilations ne " +"fournissant aucune information utile. À l’inverse, un modèle plus lent peut " +"être plus économique s’il trouve plus tôt une expérience utile. La " +"comparaison doit inclure ces coûts." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"Compter les résultats acceptés aide aussi à interpréter les progrès " +"intermédiaires. Un {ph0}candidat pour la sauvegarde des replays{ph1} de TH09" +" semblait prometteur : la fonction compilée avait la taille attendue. " +"Pourtant, la comparaison complète montrait encore des différences " +"importantes. Un autre ordre des instructions peut donner l’impression que le" +" candidat se rapproche sans résoudre le problème de fond. Ces diagnostics " +"guident l’expérience suivante, mais je vérifierais toute récompense pour ce " +"rapprochement avec le contrôle complet d’acceptation." + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"Je serais intéressé par la tendance de ces résultats. Si un modèle d’IA " +"spécialisé fonctionne bien au sein d’une famille de compilateurs familière, " +"cet avantage survit-il à un changement de chaîne d’outils ? Et une fois que " +"les deux modèles d’IA ont une bonne récupération, combien la formation " +"ajoute-t-elle encore ? Les réponses nous aideraient à décider où chaque type" +" de modèle est le plus utile." + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "Quel type d’agent IA cela suggère-t-il ?" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"Si les modèles s’avèrent utiles à différentes étapes, un arrangement utile " +"pourrait être un agent large ayant accès à un modèle d’IA spécialisé. Une " +"fois qu’une tâche devient une recherche familière du compilateur, elle peut " +"demander des candidats au modèle d’IA spécialisé. Si les résultats n’ont " +"plus de sens, l’agent au sens large pourrait revenir aux preuves cibles ou " +"enquêter sur la mesure elle-même." + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "" +"Dans cet arrangement, la spécialisation devient un outil que l’agent peut " +"choisir au fur et à mesure que l’enquête se développe. L’agent conserve la " +"liberté de changer de direction qui a rendu possible les percées " +"antérieures." + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"Cela découle naturellement du virage industriel que j’ai décrit dans l’essai" +" précédent. Être capable de mener beaucoup plus d’expériences change la " +"façon dont nous organisons le travail. Cela nous donne également une raison " +"de nous demander quelles décisions nécessitent un jugement large et " +"lesquelles s'améliorent grâce à une expérience répétée avec un métier " +"particulier." + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"Pour l'instant, le modèle général le plus puissant a gagné sa place dans mon" +" travail en résolvant des problèmes que j'avais laissés en suspens. Ces " +"réussites me donnent envie d'étudier le processus : quelle part dépend de " +"ses capacités générales, et quelle part pourrait être confiée à un modèle " +"formé pour ce type de reconstruction ?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "" +"{ph0}Les référentiels nous permettent de tester la question.{ph1} J'aimerais" +" utiliser cet enregistrement pour établir la comparaison et voir ce que nous" +" apprenons." + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "Attribution de preuves et de modèles" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"Les exemples décrivent des comparaisons historiques au niveau des fonctions " +"enregistrées dans les validations liées. Les vérifications d'exécution du " +"jeu complet sont des étapes distinctes. Les enregistrements sources et " +"correspondants ont été examinés le 13 octobre 2026." + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"L'étiquette TH09 {ph0} signifie GPT-6-Astra. Le modèle associé à {ph1} a " +"changé au fil du temps, de sorte que cette étiquette à elle seule ne peut " +"pas identifier le modèle utilisé dans une exécution spécifique. Les noms de " +"modèles explicites dans les autres commits cités fournissent l'attribution " +"enregistrée. Ces historiques n'incluent pas de mesures cohérentes du coût ou" +" de l'effort pour chaque exécution." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "" +"{ph0}TH09 durées de vie des objets temporaires :{ph1} la {ph2}examen du " +"contexte précédent{ph3} et la {ph4}reconstruction complète vérifiée par une " +"recompilation propre à partir de la source{ph5}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"{ph0}Callback Front de TH09 :{ph1} {ph2}régions de diagnostic non " +"concordantes{ph3}, {ph4}nouveau graphe de contrôle d'Astra{ph5} et " +"{ph6}vérification de recompilation acceptée{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}Connaissance du compilateur :{ph1} {ph2}TH095 réutilisation du " +"comportement du compartiment d'identifiant{ph3}, {ph4}TH04 code source du " +"joueur et ordre de l'éditeur de liens{ph5} et {ph6}Luna reconstruction " +"complète de la fonction de création d'ennemis de TH09{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}Contrôles et diagnostics :{ph1} {ph2}TH08 audit de constantes à virgule" +" flottante{ph3}, {ph4}TH08 investigation numérique{ph5} et {ph6}TH09 " +"reconstruction permettant de sauvegarder les relectures{ph7}." + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "" +"Les comparaisons proposées de modèles spécialisés et de formation RL sont " +"des expériences futures. Les histoires de projets les motivent. Aucun modèle" +" spécialisé formé n'a été évalué pour cet essai." + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "L'ingénierie inverse nécessite-t-elle un modèle plus grand ? | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "" +"Ce que la reconstruction Touhou m'a appris sur les modèles généraux, les " +"modèles spécialisés et l'apprentissage pour proposer de meilleures " +"hypothèses à partir des retours du compilateur." + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "Sur cette page" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "Modèles et essai d'ingénierie inverse" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "Expériences de reconstruction sélectionnées" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "Haut de page" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "" +"Les {ph0}notes détaillées sur les preuves{ph1} présentent les comparaisons " +"enregistrées et le contexte des expériences." + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "Par N0zoM1z0 · 13 octobre 2026 · Brouillon à relire" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "Guide d’installation" diff --git a/website/locales/id/messages.po b/website/locales/id/messages.po index 6faa06dad..92d94c93a 100644 --- a/website/locales/id/messages.po +++ b/website/locales/id/messages.po @@ -32,18 +32,18 @@ msgid "Thoughts on reverse engineering." msgstr "Pemikiran tentang rekayasa terbalik." #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "Rekonstruksi permainan{ph0}Esai" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "Revolusi industri dalam rekayasa terbalik" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " @@ -53,19 +53,20 @@ msgstr "" " tentang agen, verifikasi, dan pengetahuan yang digabungkan di seluruh " "proyek." -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "Baca artikelnya" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "Oleh N0zoM1z0 · 10 Oktober 2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -101,6 +102,8 @@ msgstr "" " REA dan AI." #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -137,6 +140,7 @@ msgstr "" "pengkodean Anda." #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -157,6 +161,7 @@ msgid "REA home" msgstr "Beranda REA" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -177,6 +182,7 @@ msgid "Main navigation" msgstr "Navigasi utama" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -197,6 +203,7 @@ msgid "REA on GitHub" msgstr "REA di GitHub" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -217,6 +224,7 @@ msgid "Join REA on Discord" msgstr "Gabung REA di Discord" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -236,7 +244,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "Ikuti REA di X" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "Kembali ke atas" @@ -11654,6 +11662,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "Jarak yang sama: 256 ÷ 16 = 16 satuan sudut = 22,5°" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -11674,6 +11683,7 @@ msgid "Showcases" msgstr "Studi kasus" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -11694,6 +11704,7 @@ msgid "Blog" msgstr "Blog" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -11714,6 +11725,7 @@ msgid "Get started" msgstr "Mulai" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -11733,7 +11745,8 @@ msgctxt "shared" msgid "Guides" msgstr "Panduan" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -11753,7 +11766,8 @@ msgctxt "shared" msgid "Source" msgstr "Kode sumber" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -11773,7 +11787,8 @@ msgctxt "shared" msgid "MIT license" msgstr "Lisensi MIT" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -11793,7 +11808,8 @@ msgctxt "shared" msgid "Join the community" msgstr "Gabung komunitas" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -12758,6 +12774,1391 @@ msgstr "" "server MCP Everywhere untuk memeriksa lalu lintas yang direkam bersama agen " "Anda." +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "Model khusus{ph0}Esai" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "Apakah rekayasa balik membutuhkan model yang lebih besar?" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "" +"Pelajaran dari rekonstruksi Touhou tentang model umum, model khusus, dan " +"pembelajaran dari umpan balik kompiler." + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Oleh N0zoM1z0 · 13 Oktober 2026" + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "Lewati ke konten" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "{ph0}Beranda{ph1} / {ph2}Blog{ph3} / Model dan rekayasa balik" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "Esai" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "Apakah rekayasa balik memerlukan model yang lebih besar?" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Oleh N0zoM1z0 · 13 Oktober 2026" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "Poin utama" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "" +"{ph0}Kemampuan model memengaruhi hipotesis mana yang dapat diajukan oleh " +"agen AI.{ph1} Sesi berikutnya memecahkan masalah yang belum terselesaikan " +"oleh pekerjaan sebelumnya." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "" +"{ph0}Kompiler yang familiar menawarkan pola konkret untuk dipelajari model " +"khusus.{ph1} Beberapa kecocokan kode mesin yang tepat bergantung pada pola " +"kode sumber spesifik yang dapat digunakan kembali." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "" +"{ph0}Sertakan pengetahuan repositori dalam perbandingan yang adil.{ph1} " +"Model yang lebih kecil dengan pengambilan pengetahuan yang baik mungkin " +"sudah memiliki informasi yang cukup untuk membuat kemajuan." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "" +"{ph0}Latih model untuk memilih eksperimen berguna berikutnya, dan uji " +"pemeriksanya.{ph1} Masukan hanya berguna jika pemeriksa memverifikasi hal " +"yang benar." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "" +"{ph0}Evaluasi hasil rekonstruksi terverifikasi beserta waktu dan biaya.{ph1}" +" Itulah yang ingin saya ukur untuk alur kerja agen AI yang lengkap." + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "Dalam artikel ini" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}Apa yang berubah dengan model yang lebih kuat?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}Mengapa mengambil spesialisasi?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}Di mana pengalaman ini harus disimpan?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}Pelajari eksperimen bermanfaat berikutnya{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}Pembelajaran rekayasa balik dan penguatan{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}Ketika pemeriksa salah{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}Sebuah perbandingan yang layak untuk dijalankan{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}Agen AI macam apa yang disarankan di sini?{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "Apa yang berubah dengan model yang lebih kuat?" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"Sejak Agustus 2026, saya telah mengeksplorasi seberapa banyak rekayasa balik" +" yang dapat dilakukan agen dengan akses ke suatu program dan cara untuk " +"memeriksa kerjanya. Sebagian besar pengalaman saya berasal dari " +"merekonstruksi game, terutama Touhou. Karena saya telah mengubah model, " +"repositori menyimpan catatan tentang apa yang berhasil dipulihkan oleh " +"setiap sesi." + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"Sebagian besar pekerjaan tersebut bertujuan untuk rekonstruksi yang tepat: " +"kami mengkompilasi sumber yang dikelola di bawah rantai alat historis dengan" +" versi tetap dan memeriksa apakah sumber tersebut mereproduksi fungsi " +"target. Ketika model selanjutnya berhasil ketika pekerjaan sebelumnya " +"terhenti, perubahan sumber menunjukkan apa yang memungkinkan kemajuan " +"tersebut." + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "Variabel sementara membutuhkan masa hidup yang tumpang tindih" + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"Sebagian besar logika fungsi serangan TH09 telah direkonstruksi, namun " +"kompiler masih menyimpan hasil sementara yang berbeda dari aslinya. Masalah " +"yang tersisa adalah berapa lama hasil tersebut perlu bertahan dan kapan " +"penyimpanannya dapat digunakan kembali." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"Catatan sesi {ph0}GPT-6-Sol{ph1} melaporkan ketidakcocokan ini setelah " +"menguji beberapa pengaturan kode sumber biasa. Ketika {ph2}GPT-6.1-Sol " +"memeriksa masalahnya lagi{ph3}, ia mengajukan hipotesis yang berguna tentang" +" masa hidup variabel-variabel sementara ini." + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"Fungsi tersebut memberikan hasil sementara dan menyalinnya ke posisi " +"animasi. Di C++, hasil sementara tetap aktif hingga ekspresi yang " +"menggunakannya selesai. Mengelompokkan operasi nyata ke dalam satu ekspresi " +"membuat hasil tersebut tetap hidup, sehingga kompiler tidak dapat lagi " +"menggunakan penyimpanan yang sama untuk semuanya." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"Salah satu hasil masih berbagi penyimpanan dengan nilai yang nantinya " +"digunakan untuk pemeriksaan tabrakan. Memberikan nilai tersebut seumur " +"hidupnya akan menyelesaikan sisa tumpang tindih. Setelah beberapa eksperimen" +" yang ditargetkan, {ph0}kompilasi ulang yang bersih dari sumber " +"mengonfirmasi bahwa seluruh fungsi cocok{ph1}." + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"Saya tertarik pada bagaimana penemuan dan pengujian saling mendukung. " +"Hipotesis tentang masa hidup objek yang bersifat sementara memberikan arah " +"baru bagi agen AI. Umpan balik dari kompiler membantunya menyempurnakan " +"hipotesis tersebut menjadi susunan kode sumber yang cocok." + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "Grafik aliran kontrol yang berbeda" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"Fungsi TH09 kedua menunjukkan mengapa arah baru itu penting. Di sini " +"kendalanya adalah bagaimana beberapa cabang membagikan karya akhirnya. " +"{ph0}Pekerjaan sebelumnya GPT-6.1-Sol{ph1} memiliki bagian-bagian fungsi " +"yang cocok, namun cabang-cabangnya masih digabungkan secara berbeda dari " +"aslinya." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}GPT-6-Astra mengubah grafik aliran kontrol di sekitarnya{ph1}. Jalur " +"utama sekarang mengarah ke pembaruan akhir bersama dan kembalinya. Dalam " +"struktur sumber tersebut, kompiler menggabungkan cabang-cabang dengan cara " +"yang sama seperti aslinya. Fungsi keseluruhannya cocok, dan {ph2}pemeriksaan" +" pembangunan kembali secara terpisah mengonfirmasi hal tersebut{ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}Mengubah representasi membuka ruang pencarian yang lebih " +"produktif.{ph1} Kedua kasus tersebut memberi saya alasan untuk menganggap " +"serius kemampuan model umum: agen dapat terus mencoba variasi lokal untuk " +"waktu yang lama sebelum menemukan cara yang lebih baik untuk mengekspresikan" +" pekerjaan di sekitarnya." + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"Pada saat yang sama, sesi selanjutnya dimulai dengan sumber sebelumnya dan " +"mencatat kegagalan. Akumulasi pekerjaan itu adalah bagian dari keuntungan " +"mereka. Sejarah memungkinkan kita memeriksa penemuan-penemuan dan " +"pemeriksaannya; perbandingan terkontrol akan membantu memisahkan pengaruh " +"model dari pengalaman yang diwarisinya." + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"Inilah yang membuat pertanyaan ini menarik bagi saya. Beberapa kemajuan " +"datang dari penemuan representasi baru. Sebagian besar pekerjaan yang " +"tersisa melibatkan pengujian pengaturan kode sumber yang berbeda terhadap " +"kompiler yang sudah dikenal. Seberapa banyak hal ini memerlukan kemampuan " +"penalaran yang luas? Berapa banyak yang dapat dipelajari suatu model dengan " +"bekerja berulang kali menggunakan compiler dan kode tersebut?" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "Mengapa model AI khusus dapat berfungsi dengan baik?" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"Touhou memberi kita alasan konkret untuk mengharapkan pengalaman itu " +"membantu. Sebagian besar kode permainan berasal dari penulis yang sama, ZUN," +" jadi kebiasaan berulang adalah asumsi awal yang masuk akal. Repositori " +"mendukung hal tersebut dengan contoh-contoh yang berguna: loop terkait dan " +"pengaturan pembantu telah memberikan hipotesis di seluruh game." + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "" +"Pola sumber tersebut menjadi lebih spesifik ketika kita menyertakan " +"kompiler. Dalam versi dan rangkaian opsi tertentu, perubahan kecil pada " +"sumber dapat menghasilkan perbedaan berulang dalam kode mesin. Beberapa dari" +" perbedaan tersebut ternyata tidak jelas." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"Di TH095, misalnya, {ph0}bahkan nama variabel lokal dapat memengaruhi tempat" +" VC7.1 menyimpannya{ph1}. Memindahkan deklarasinya tidak menyelesaikan tata " +"letak penyimpanan. Namun, fungsi latar belakang sebelumnya telah " +"mengungkapkan pola penamaan yang mempengaruhi pilihan kompiler. Hal ini " +"menunjukkan hipotesis yang lebih menjanjikan untuk {ph2}merekonstruksi " +"{ph3}{ph4}." + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "" +"Menggunakan kembali pola tersebut untuk variabel ukuran file menghasilkan " +"tata letak yang diperlukan tanpa menambahkan penyimpanan. Fungsi penuh " +"kemudian dicocokkan." + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "" +"Ini adalah detail yang sangat spesifik yang mungkin tidak diketahui oleh " +"model AI tujuan umum saat pertama kali mengalami masalah. Model yang " +"dikhususkan untuk kompiler ini dapat melihat banyak kasus seperti itu dan " +"mempelajari variasi kode sumber mana yang layak untuk diuji terlebih dahulu." + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"Peluangnya sangat jelas dalam masalah pencocokan akhir dimana kita sudah " +"memahami perilakunya. Kami kemudian menanyakan pengaturan kode sumber biasa " +"mana yang diubah oleh kompiler ini menjadi instruksi yang diamati. " +"Spesialisasi dapat membantu model mengusulkan bentuk-bentuk tersebut dengan " +"lebih efisien, sementara target tetap menentukan hipotesis mana yang " +"bertahan." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"Pola yang berguna harus mempertahankan konteksnya. TH08 menggunakan versi " +"Visual C++ yang lebih lama dari TH095 dan TH09. TH04 menggunakan compiler " +"yang berbeda dari era DOS. {ph0}rekonstruksi kode pemain{ph1} memerlukan " +"hipotesis berbeda tentang pola kode sumber dan bagaimana kode yang " +"dikompilasi dihubungkan ke dalam file yang dapat dieksekusi. Memiliki " +"penulis yang sama memberi kita ekspektasi awal, namun setiap target memberi " +"tahu kita apakah target tersebut berlaku. Model khusus perlu membedakan " +"konteks-konteks ini." + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "Di mana pengalaman ini harus disimpan?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"Sebelum memutuskan untuk mengajarkan pola-pola tersebut melalui pelatihan " +"model, saya akan melihat pengetahuan yang sudah kita simpan di gudang. Dalam" +" {ph0}esai sebelumnya{ph1}, saya menulis tentang hal ini yang menjadi memori" +" kerja proyek. Memori tersebut mencakup pelajaran kompiler, beserta " +"sumbernya dan eksperimen gagal yang menjadikannya berguna." + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"Dengan mengambil catatan tersebut, agen dapat memulai dengan hasil yang " +"diketahui dan memeriksa bagaimana kami mencapainya. Hal ini juga dapat " +"menghindari alternatif-alternatif yang telah gagal dalam konteks yang sama. " +"Titik awal ditingkatkan tanpa mengubah parameter model yang dilatih." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"Saat merekonstruksi fungsi TH09 untuk menciptakan musuh, {ph0}sesi " +"GPT-6-Luna-max{ph1} mengambil hipotesis dari kode sumber TH08 terkait. Kode " +"sebelumnya menyarankan cara mengatur loop dan menangani kegagalan di " +"dalamnya. Bukti TH09 sendiri memberikan detail khusus game tersebut. " +"Pembangunan kembali dari sumber mengonfirmasi bahwa fungsi lengkapnya cocok." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}\"Model tidak mengetahui kekhasan kompiler\" dan \"model tidak dapat " +"menggunakannya\" adalah masalah yang berbeda.{ph1} Pengambilan mungkin " +"memecahkan masalah pertama, namun mengubah fakta tersebut menjadi kandidat " +"yang berguna masih membutuhkan usaha. Dan jika kandidat kode sumber gagal, " +"model harus memutuskan apa arti hasil tersebut untuk percobaan berikutnya. " +"Mengetahui pola yang relevan hanyalah awal dari proses itu." + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"Oleh karena itu, saya akan menyertakan model AI serba guna yang lebih kecil " +"dengan pengambilan yang baik dalam perbandingan apa pun. Memberikan " +"perpustakaan pengalaman yang sama akan membantu kami mengidentifikasi apa " +"saja yang ditambahkan oleh pelatihan: perolehan kandidat yang lebih baik, " +"keputusan yang lebih baik setelah adanya masukan, atau keduanya." + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "Pelajari eksperimen bermanfaat berikutnya" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"Keputusan-keputusan setelah mendapat masukan adalah hal yang paling ingin " +"saya pelajari. Dalam rekonstruksi agenik, model mengajukan penjelasan dan " +"mengujinya terhadap program. Bahkan ketika kode sumber kandidat gagal, " +"hasilnya dapat mempersempit kemungkinan yang tersisa dan menyarankan " +"percobaan berikutnya yang lebih berguna." + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "" +"Perhatikan kembali contoh hasil sementara. Sumber akhirnya menunjukkan " +"pengaturan yang berhasil, namun rute ke sumber tersebut berisi lebih banyak " +"informasi. Setiap eksperimen berikut membantu mengidentifikasi apa yang " +"masih perlu diubah." + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "Eksperimen" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "Apa yang diajarkan hasilnya kepada kita" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "Coba cara lain untuk menyalin hasilnya" + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "Kode copynya berubah, tapi fungsinya tetap berbeda." + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "Gunakan nilai yang dikembalikan secara langsung" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "" +"Penyalinan mengikuti pola aslinya, namun penyimpanan sementara tetap " +"berbeda." + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "Jaga agar semua variabel sementara tetap valid pada waktu yang sama" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "" +"Mereka mendapatkan penyimpanan terpisah, namun masih tumpang tindih dengan " +"nilai yang digunakan nanti untuk pemeriksaan tabrakan." + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "Pisahkan nilai pemeriksaan tabrakan" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "" +"Kompilasi ulang yang bersih dari sumber mengonfirmasi kecocokan yang " +"lengkap." + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "" +"Eksperimen yang dipilih dari rekonstruksi fungsi serangan di atas, " +"dikelompokkan berdasarkan apa yang diajarkannya kepada kita." + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"Catatan pelatihan yang menjaga urutan ini dapat mengajarkan lebih dari " +"sekedar sumber akhir saja. Ini menghubungkan setiap perubahan yang diusulkan" +" dengan hasil yang diamati dan keputusan berikutnya. Mempertahankan variasi " +"yang tidak efektif juga penting: variasi tersebut akan memberi tahu agen " +"selanjutnya hipotesis mana yang telah diuji dalam konteks tersebut." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}Saya ingin model mempelajari cara menggunakan masukan.{ph1} Hasil yang " +"netral adalah alasan untuk mempertimbangkan kembali variasi; ketidakcocokan " +"yang berubah mungkin menunjukkan penyebab lain. Ketika suntingan lokal tidak" +" lagi bersifat informatif, agen harus dapat mengunjungi kembali representasi" +" sumber atau memeriksa bukti lagi." + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"Belajar membuat pilihan tersebut membutuhkan otonomi. Terkadang langkah " +"berikutnya yang berguna adalah memeriksa pemanggil lain daripada " +"mengkompilasi hasil edit lainnya. Urutan penulisan ulang yang diperlukan " +"akan menghilangkan pilihan tersebut, bersama dengan bagian dari perilaku " +"yang kita ingin model pelajari." + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "Mengapa rekayasa balik menarik untuk pembelajaran penguatan" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"Rekonstruksi dengan lingkup yang jelas memberi lingkungan praktis untuk " +"mempelajari pilihan ini. Setelah versi target dan kompiler ditetapkan, " +"banyak eksperimen kode sumber memberi umpan balik yang cepat dan dapat " +"diulang. Agen bisa mengompilasi kandidat, memeriksa perbedaan, lalu memilih " +"langkah berikutnya." + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"Pembelajaran penguatan dapat melatih proses pengambilan keputusan melalui " +"umpan balik yang diterimanya. Kandidat yang diterima melalui pemeriksaan " +"tertentu memberi kita hasil yang konkrit, sementara rangkaian upaya " +"memungkinkan kita mengamati berapa banyak usaha yang diperlukan untuk " +"mencapainya." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"Sudah ada penelitian yang mendukung arah ini. {ph0}LLM4Decompile{ph1} " +"mempelajari model yang dikhususkan untuk dekompilasi. " +"{ph2}AutoDecompiler{ph3} melatih penyempurnaan multi-putaran menggunakan " +"compiler dan masukan eksekusi. Studi mereka fokus pada pemulihan fungsional." +" Untuk pekerjaan ini, saya akan menggunakannya sebagai titik awal untuk " +"tugas terkait menemukan sumber yang cocok dengan keluaran kompiler historis." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"Namun, untuk mencapai tugas yang terdefinisi dengan baik, pertama-tama kita " +"perlu menetapkan sumber daya yang dimiliki suatu fungsi atau merancang cara " +"baru untuk mengamati perilaku program saat berjalan. Di TH08, misalnya, " +"{ph0}perbedaan tabrakan mengarah kembali ke cara program asli menangani " +"penghitungan floating-point{ph1}. Sebelum agen dapat menguji koreksi yang " +"berguna, agen harus menentukan apa yang diukur." + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "" +"Hal ini menunjukkan adanya peran lain dari model yang berkemampuan luas: " +"membantu membuat masalah dapat diperiksa. Setelah pemeriksaan tersebut " +"dilakukan, kami dapat menyelidiki sejauh mana kebijakan penelusuran yang " +"dipelajari dapat diterapkan." + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "Ketika pemeriksa salah" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"Saat suatu pemeriksaan dipakai untuk pelatihan, cakupannya menjadi bagian " +"dari lingkungan belajar. Saya menyebut acuan atau alat pemeriksa itu oracle." +" Bahkan jawaban yang dapat diulang harus dipahami berdasarkan apa yang " +"benar-benar diperiksanya." + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"TH08 menunjukkan seberapa banyak yang bisa disembunyikan di luar cakupan " +"itu. Beberapa fungsi yang direkonstruksi memberikan perbandingan yang tepat " +"dengan konstanta floating-point yang salah. Pembanding menyesuaikan alamat " +"yang direlokasi sebelum memeriksa instruksi, namun pembanding memeriksa " +"nilai di balik alamat tersebut hanya jika nilai tersebut telah dicatat " +"secara eksplisit untuk verifikasi. Referensi literal lainnya bisa lolos " +"tanpa diperiksa nilainya." + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"Untuk mengatasi kesenjangan ini, {ph0}audit yang lebih luas{ph1} menemukan " +"konstanta yang salah pada fungsi yang telah lolos verifikasi. Dalam satu " +"perhitungan, kode sumber yang direkonstruksi menambahkan {ph2}, sedangkan " +"kode sumber asli menambahkan {ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}Model yang diberi imbalan melalui pemeriksaan verifikasi lama dapat " +"belajar menghasilkan rekonstruksi yang salah.{ph1} Kami tidak melatih model " +"RL menggunakan pemeriksa tersebut. Kegagalan yang kami amati ada pada " +"pemeriksaan itu sendiri. Namun jika kita menggunakannya sebagai hadiah, " +"titik buta yang sama akan menjadi bagian dari lingkungan belajar." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"Tes fungsional dapat memiliki titik buta serupa. {ph0}Penelitian yang " +"menggunakan fuzzing diferensial pada dekompiler LLM{ph1} menemukan perbedaan" +" perilaku di luar pengujian yang disediakan. Oleh karena itu, kita perlu " +"memahami tes kelulusan dalam kaitannya dengan kasus-kasus yang dilakukannya." +" Demikian pula, kecocokan instruksi harus dipahami dalam kaitannya dengan " +"byte dan data yang diverifikasi." + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"Sebelum menggunakan salah satu jenis cek verifikasi sebagai hadiah, saya " +"akan mengujinya dengan hasil yang sengaja salah. Saya juga akan memisahkan " +"penerimaan akhir dari kode sumber yang dapat diedit oleh agen AI. Model " +"harus lolos verifikasi dengan merekonstruksi program dengan benar. Jika " +"tidak, hanya dengan menyalin array byte dari target dapat menipu sistem " +"penilaian yang naif tanpa memulihkan kode sumber yang berguna." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "" +"{ph0}Memperbaiki model yang belajar dan memperbaiki pemeriksanya merupakan " +"bagian dari masalah penelitian yang sama.{ph1} Semakin baik model " +"mengoptimalkan umpan balik yang kita berikan, semakin penting memahami umpan" +" balik itu sendiri." + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "Sebuah perbandingan yang layak untuk dijalankan" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"Dengan pemeriksaan tersebut, saya akan memulai perbandingan pada rangkaian " +"tugas VC7.1 yang tetap. Pertama, saya akan menetapkan dasar untuk model AI " +"tujuan umum yang kuat dan model yang lebih kecil. Menambahkan pengetahuan " +"repositori ke model yang lebih kecil akan menunjukkan perubahan pengambilan " +"apa. Dari sana, spesialisasi yang diawasi dan versi terlatih RL akan " +"memungkinkan kita memeriksa apa saja yang ditambahkan dalam pelatihan." + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"Agar perbandingan tersebut informatif, setiap model akan menerima bukti dan " +"alat target yang sama. Untuk perbandingan khusus pelatihan, saya juga akan " +"mempertahankan model dasar dan pengetahuan yang tersedia. Uji coba berulang " +"akan membantu membedakan strategi pencarian yang andal dari kandidat solusi " +"yang berhasil secara kebetulan." + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"Saya kemudian akan memisahkan dua kondisi awal: merekonstruksi suatu fungsi " +"dari instruksinya, dan menutup beberapa perbedaan terakhir dalam sumber yang" +" dipertahankan. Model AI khusus mungkin sangat baik dalam tugas kedua, " +"sementara model AI tujuan umum melakukan banyak pekerjaan yang diperlukan " +"untuk mencapainya. Mengukurnya secara terpisah akan mengungkapkan pembagian " +"kerja tersebut." + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"Kedua tugas memerlukan contoh uji yang tidak ada dalam data pelatihan maupun" +" bahan retrieval. Game Touhou yang terkait berbagi kode engine. " +"Mengecualikan satu game saja masih bisa menyisakan fungsi yang hampir " +"identik dalam data pelatihan. Saya akan menyisihkan seluruh kelompok kode " +"yang terkait, dan memastikan jawaban terverifikasinya tidak masuk ke data " +"pelatihan ataupun pustaka retrieval." + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"Untuk contoh-contoh ini, hasilnya akan berupa kecocokan yang lengkap dan " +"terverifikasi secara independen. Anggaran yang sama untuk proposal kandidat " +"atau upaya kompilasi akan membantu membandingkan kualitas pencarian. " +"Mengukur total waktu dan biaya, termasuk kompilasi, akan menunjukkan apakah " +"kualitas tersebut menghasilkan alur kerja yang efisien. Biaya pelatihan " +"harus diukur secara terpisah." + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"Kedua pengukuran itu penting. Proposal yang murah dapat menyebabkan alur " +"kerja yang mahal jika menyebabkan lebih banyak kompilasi yang tidak " +"memberikan informasi berguna. Sebaliknya, model yang lebih lambat mungkin " +"lebih ekonomis jika model tersebut menemukan eksperimen yang berguna lebih " +"cepat. Perbandingannya harus mencakup biaya-biaya ini." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"Menghitung hasil yang diterima juga menjaga kemajuan sementara tetap dalam " +"perspektif. Salah satu TH09 {ph0}kandidat penyimpanan ulang{ph1} tampak " +"menjanjikan karena fungsi yang dikompilasi memiliki ukuran yang diharapkan, " +"namun perbandingan penuh masih menemukan perbedaan besar. Perubahan dalam " +"cara compiler menyusun instruksi juga dapat membuat kandidat tampak lebih " +"dekat dengan target tanpa menyelesaikan masalah mendasarnya. Diagnostik " +"semacam itu dapat memandu eksperimen berikutnya, namun saya akan memvalidasi" +" imbalan apa pun karena \"mendekati\" dengan pemeriksaan penerimaan penuh." + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"Saya tertarik dengan pola hasil ini. Jika model AI khusus dapat berfungsi " +"dengan baik dalam rangkaian kompiler yang sudah dikenal, apakah keunggulan " +"tersebut dapat bertahan jika terjadi perubahan rantai alat? Dan ketika kedua" +" model AI memiliki pengambilan yang baik, berapa banyak lagi yang bisa " +"ditambahkan oleh pelatihan? Jawabannya akan membantu kita memutuskan model " +"mana yang paling berguna." + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "Agen AI macam apa yang disarankan di sini?" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"Jika model-model tersebut terbukti membantu pada tahap-tahap yang berbeda, " +"pengaturan yang berguna mungkin adalah agen luas yang memiliki akses ke " +"model AI khusus. Setelah tugas menjadi pencarian kompiler yang familier, " +"tugas tersebut dapat menanyakan kandidat pada model AI khusus. Jika hasilnya" +" tidak masuk akal, agen yang lebih luas dapat kembali ke bukti target atau " +"menyelidiki pengukuran itu sendiri." + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "" +"Dalam pengaturan tersebut, spesialisasi menjadi alat yang dapat dipilih agen" +" seiring berkembangnya penyelidikan. Agen mempunyai kebebasan untuk mengubah" +" arah yang memungkinkan terobosan sebelumnya." + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"Hal ini tentu saja mengikuti pergeseran industri yang saya jelaskan di esai " +"sebelumnya. Mampu menjalankan lebih banyak eksperimen mengubah cara kami " +"mengatur pekerjaan. Hal ini juga memberi kita alasan untuk mempertanyakan " +"keputusan mana yang memerlukan pertimbangan luas dan mana yang ditingkatkan " +"melalui pengalaman berulang-ulang dengan bidang tertentu." + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"Untuk saat ini, model umum terkuat mendapat tempat dalam alur kerja saya " +"karena menyelesaikan masalah yang sebelumnya belum terpecahkan. Keberhasilan" +" itu membuat saya ingin mempelajari prosesnya: seberapa banyak bergantung " +"pada keluasan kemampuan model, dan seberapa banyak bisa dikerjakan oleh " +"model yang dilatih khusus untuk jenis rekonstruksi ini?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "" +"{ph0}Repositori memberi kita cara untuk menguji pertanyaan tersebut.{ph1} " +"Saya ingin menggunakan data tersebut untuk membuat perbandingan dan melihat " +"apa yang kita pelajari." + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "Bukti dan atribusi model" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"Contoh-contoh ini menjelaskan perbandingan tingkat fungsi historis yang " +"dicatat dalam penerapan tertaut. Pemeriksaan waktu proses keseluruhan " +"permainan adalah pencapaian yang terpisah. Sumber dan catatan pencocokan " +"ditinjau pada 13 Oktober 2026." + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"Label TH09 {ph0} berarti GPT-6-Astra. Model yang terkait dengan {ph1} " +"berubah seiring waktu, sehingga label saja tidak dapat mengidentifikasi " +"model yang digunakan dalam proses tertentu. Nama model eksplisit dalam " +"commit lain yang dikutip memberikan atribusi yang tercatat. Riwayat ini " +"tidak mencakup pengukuran biaya atau upaya yang konsisten untuk setiap " +"proses." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "" +"{ph0}TH09 masa hidup objek sementara:{ph1} {ph2}tinjauan konteks " +"sebelumnya{ph3} dan {ph4}rekonstruksi lengkap yang diverifikasi melalui " +"kompilasi ulang yang bersih dari sumber{ph5}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"{ph0}TH09 Front callback:{ph1} {ph2}wilayah diagnostik yang tidak " +"cocok{ph3}, {ph4}Astra grafik aliran kontrol baru{ph5} dan {ph6}pemeriksaan " +"kompilasi ulang yang diterima{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}Pengetahuan compiler:{ph1} {ph2}TH095 penggunaan kembali perilaku " +"identifier-bucket{ph3}, {ph4}TH04 kode sumber pemain dan urutan linker{ph5} " +"dan {ph6}Luna rekonstruksi lengkap fungsi penciptaan musuh TH09{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}Pemeriksaan dan diagnostik:{ph1} {ph2}TH08 audit konstan floating-" +"point{ph3}, {ph4}TH08 investigasi numerik{ph5} dan {ph6}TH09 rekonstruksi " +"penyimpanan ulangan{ph7}." + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "" +"Perbandingan yang diusulkan antara model khusus dan pelatihan RL adalah " +"eksperimen di masa depan. Sejarah proyek memotivasi mereka. Tidak ada model " +"khusus terlatih yang dievaluasi untuk esai ini." + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "Apakah rekayasa balik memerlukan model yang lebih besar? | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "" +"Apa yang saya pelajari dari rekonstruksi Touhou tentang model umum, model " +"khusus, dan cara belajar mengajukan hipotesis yang lebih baik melalui umpan " +"balik kompiler." + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "Di halaman ini" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "Model dan esai rekayasa balik" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "Eksperimen rekonstruksi yang dipilih" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "Kembali ke atas" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "" +"{ph0}Catatan bukti terperinci{ph1} memuat perbandingan yang dicatat dan " +"konteks eksperimen." + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "Oleh N0zoM1z0 · 13 Oktober 2026 · Draf untuk ditinjau" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "Panduan pemasangan" diff --git a/website/locales/it/messages.po b/website/locales/it/messages.po index fdebe81d8..516e09283 100644 --- a/website/locales/it/messages.po +++ b/website/locales/it/messages.po @@ -32,18 +32,18 @@ msgid "Thoughts on reverse engineering." msgstr "Riflessioni sul reverse engineering." #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "Gioco ricostruzione{ph0}Saggio" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "La rivoluzione industriale nel reverse engineering" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " @@ -52,19 +52,20 @@ msgstr "" "Che manuale RE e ricostruire TH08, TH095 e TH04 mi ha insegnato circa gli " "agenti, la verifica e la conoscenza che composti attraverso i progetti." -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "Leggi l'articolo" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "Di N0zoM1z0 * 10 ottobre 2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -100,6 +101,8 @@ msgstr "" "e agenti AI." #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -136,6 +139,7 @@ msgstr "" "di codifica." #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -156,6 +160,7 @@ msgid "REA home" msgstr "Home di REA" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -176,6 +181,7 @@ msgid "Main navigation" msgstr "Navigazione principale" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -196,6 +202,7 @@ msgid "REA on GitHub" msgstr "REA su GitHub" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -216,6 +223,7 @@ msgid "Join REA on Discord" msgstr "Unisciti a REA su Discord" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -235,7 +243,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "Segui REA su X" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "Torna in alto" @@ -11712,6 +11720,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "Stessa spaziatura: 256 ÷ 16 = 16 unità angolari = 22,5°" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -11732,6 +11741,7 @@ msgid "Showcases" msgstr "Casi pratici" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -11752,6 +11762,7 @@ msgid "Blog" msgstr "Blog" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -11772,6 +11783,7 @@ msgid "Get started" msgstr "Inizia" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -11791,7 +11803,8 @@ msgctxt "shared" msgid "Guides" msgstr "Guide" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -11811,7 +11824,8 @@ msgctxt "shared" msgid "Source" msgstr "Codice sorgente" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -11831,7 +11845,8 @@ msgctxt "shared" msgid "MIT license" msgstr "Licenza MIT" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -11851,7 +11866,8 @@ msgctxt "shared" msgid "Join the community" msgstr "Unisciti alla community" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -12819,6 +12835,1400 @@ msgstr "" "offline, oppure collega il server MCP di Everywhere per esaminare il " "traffico acquisito con il tuo agente." +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "Modelli specializzati{ph0}Saggio" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "Il reverse engineering ha bisogno di un modello più grande?" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "" +"Cosa suggerisce la ricostruzione di Touhou sui modelli generali, quelli " +"specializzati e l’apprendimento dal feedback del compilatore." + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Da N0zoM1z0 · 13 ottobre 2026" + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "Vai al contenuto" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "{ph0}Home{ph1} / {ph2}Blog{ph3} / Modelli e reverse engineering" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "Saggio" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "Il reverse engineering necessita di un modello più grande?" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Da N0zoM1z0 · 13 ottobre 2026" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "Punti chiave" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "" +"{ph0}La capacità del modello influisce sulle ipotesi che un agente AI può " +"proporre.{ph1} Le sessioni successive hanno risolto problemi che il lavoro " +"precedente aveva lasciato irrisolti." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "" +"{ph0}Un compilatore familiare offre modelli concreti da apprendere per un " +"modello specializzato.{ph1} Alcune corrispondenze esatte del codice macchina" +" dipendono da modelli di codice sorgente specifici e riutilizzabili." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "" +"{ph0}Includi la conoscenza del repository in un confronto equo.{ph1} Un " +"modello più piccolo con un buon recupero della conoscenza potrebbe già avere" +" informazioni sufficienti per fare progressi." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "" +"{ph0}Addestra il modello per scegliere il prossimo esperimento utile e " +"testare il suo strumento di verifica.{ph1} Il feedback è utile solo nella " +"misura in cui lo strumento verifica le cose giuste." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "" +"{ph0}Valuta i risultati verificati della ricostruzione insieme a tempi e " +"costi.{ph1} Questo è ciò che voglio misurare per il flusso di lavoro " +"completo dell'agente AI." + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "In questo articolo" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}Che cosa hanno cambiato i modelli più capaci{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}Perché specializzarsi?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}Dove dovrebbe essere archiviata questa esperienza?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}Imparare il prossimo esperimento utile{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}Reverse engineering e apprendimento per rinforzo{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}Quando il controllo di verifica è sbagliato{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}Un confronto che vale la pena fare{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}Che tipo di agente AI suggerisce questo?{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "Che cosa hanno cambiato i modelli più capaci" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"Dall'agosto 2026, ho esplorato quanto reverse engineering può eseguire un " +"agente con l'accesso a un programma e un modo per verificarne il lavoro. La " +"maggior parte della mia esperienza deriva dalla ricostruzione di giochi, in " +"particolare Touhou. Man mano che ho cambiato modello, i repository hanno " +"tenuto traccia di ciò che è riuscita a recuperare ciascuna sessione." + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"Gran parte di questo lavoro mira alla ricostruzione esatta: compiliamo il " +"sorgente mantenuto in una toolchain storica con versioni fisse e " +"controlliamo se riproduce la funzione di destinazione. Quando un modello " +"successivo riesce dove il lavoro precedente si era bloccato, le modifiche " +"alla fonte mostrano cosa ha reso possibile quel progresso." + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "Le variabili temporanee necessitavano di vite sovrapposte" + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"Gran parte della logica della funzione di attacco TH09 era già stata " +"ricostruita, ma il compilatore memorizzava ancora i risultati temporanei in " +"modo diverso dall'originale. Il problema rimanente era quanto tempo " +"occorreva a quei risultati per rimanere in vita e quando la loro " +"conservazione poteva essere riutilizzata." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"Un {ph0}GPT-6-Sol record di sessione{ph1} ha segnalato questa mancata " +"corrispondenza dopo aver testato diverse disposizioni ordinarie del codice " +"sorgente. Quando {ph2}GPT-6.1-Sol ha esaminato nuovamente il problema{ph3}, " +"ha proposto un'ipotesi utile sulla durata di queste variabili temporanee." + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"La funzione ha prodotto risultati temporanei e li ha copiati in posizioni di" +" animazione. In C++, un risultato temporaneo rimane attivo finché " +"l'espressione che lo utilizza non termina. Raggruppare le operazioni reali " +"in un'unica espressione ha mantenuto vivi insieme i risultati, quindi il " +"compilatore non poteva più riutilizzare la stessa memoria per tutti loro." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"Un risultato ha ancora spazio di archiviazione condiviso con un valore " +"utilizzato successivamente per i controlli di collisione. Dare a quel valore" +" la propria durata ha risolto la rimanente sovrapposizione. Dopo diversi " +"esperimenti mirati, {ph0}una ricompilazione pulita dal sorgente ha " +"confermato che l'intera funzione corrispondeva a{ph1}." + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"Sono interessato a come la scoperta e i test si siano supportati a vicenda. " +"L’ipotesi sulla durata temporanea degli oggetti ha dato all’agente AI una " +"nuova direzione. Il feedback del compilatore ha aiutato a perfezionare " +"quell'ipotesi in una disposizione del codice sorgente che corrispondesse." + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "Un diverso grafico del flusso di controllo" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"Una seconda funzione TH09 mostra perché questa nuova direzione può essere " +"importante. In questo caso, l’ostacolo era il modo in cui diversi rami " +"condividevano il loro lavoro finale. Il lavoro precedente di " +"{ph0}GPT-6.1-Sol{ph1} faceva corrispondere parti della funzione, ma i rami " +"si univano ancora in modo diverso dall'originale." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}GPT-6-Astra ha cambiato il grafico del flusso di controllo " +"circostante{ph1}. I percorsi principali conducono ora ad un aggiornamento " +"finale condiviso e al ritorno. In quella struttura sorgente, il compilatore " +"ha combinato i rami nello stesso modo dell'originale. La funzione completa " +"corrispondeva e un {ph2}controllo di ricostruzione separato lo ha " +"confermato{ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}La modifica della rappresentazione ha aperto uno spazio di ricerca più " +"produttivo.{ph1} Entrambi i casi mi danno un motivo per prendere sul serio " +"le capacità generali del modello: un agente può continuare a provare " +"variazioni locali per molto tempo prima di trovare un modo migliore per " +"esprimere il lavoro circostante." + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"Le sessioni successive hanno anche ereditato il codice precedente e i " +"tentativi falliti già documentati. Questo lavoro accumulato faceva parte del" +" loro vantaggio. La cronologia permette di esaminare le scoperte e le " +"verifiche; un confronto controllato aiuterebbe a separare il contributo del " +"modello da quello dell’esperienza ereditata." + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"Questo è ciò che rende la domanda interessante per me. Alcuni progressi sono" +" arrivati ​​dalla ricerca di una nuova rappresentanza. Gran parte del lavoro" +" rimanente prevedeva il test di diverse disposizioni del codice sorgente " +"rispetto a un compilatore familiare. Quanto di tutto ciò richiede un’ampia " +"capacità di ragionamento? Quanto potrebbe imparare un modello lavorando " +"ripetutamente con quel compilatore e quel codice?" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "Perché un modello di IA specializzato potrebbe funzionare bene?" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"Touhou ci dà una ragione concreta per aspettarci che quell'esperienza sia " +"d'aiuto. Gran parte del codice del gioco proviene dallo stesso autore, ZUN, " +"quindi le abitudini ricorrenti sono un presupposto di partenza ragionevole. " +"I repository lo confermano con esempi utili: cicli correlati e disposizioni " +"di supporto hanno fornito ipotesi attraverso i giochi." + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "" +"Questi modelli di origine diventano più specifici quando includiamo il " +"compilatore. In una particolare versione e insieme di opzioni, piccole " +"modifiche all'origine possono produrre differenze ripetibili nel codice " +"macchina. Alcune di queste differenze sono sorprendentemente oscure." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"In TH095, ad esempio, {ph0}anche il nome di una variabile locale potrebbe " +"influenzare dove VC7.1 l'ha memorizzata{ph1}. Lo spostamento della sua " +"dichiarazione non ha risolto il layout di archiviazione. Tuttavia, una " +"precedente funzione in background aveva rivelato un modello di denominazione" +" che influenzava la scelta del compilatore. Ciò ha suggerito un'ipotesi più " +"promettente per {ph2}ricostruire {ph3}{ph4}." + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "" +"Il riutilizzo di quel modello per la variabile della dimensione del file ha " +"prodotto il layout richiesto senza aggiungere spazio di archiviazione. La " +"funzione completa quindi corrispondeva." + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "" +"Questo è un dettaglio molto specifico che un modello di intelligenza " +"artificiale generica potrebbe non conoscere quando incontra per la prima " +"volta il problema. Un modello specializzato per questo compilatore potrebbe " +"vedere molti casi simili e apprendere quali variazioni del codice sorgente " +"vale la pena testare per prime." + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"L'opportunità è particolarmente chiara nei problemi di abbinamento finale in" +" cui ne comprendiamo già il comportamento. Ci stiamo quindi chiedendo quale " +"disposizione ordinaria del codice sorgente questo compilatore trasforma " +"nelle istruzioni osservate. La specializzazione potrebbe aiutare il modello " +"a proporre tali forme in modo più efficiente, mentre l’obiettivo determina " +"ancora quali ipotesi sopravvivono." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"Gli schemi utili devono conservare il loro contesto. TH08 usa una versione " +"di Visual C++ precedente a quella di TH095 e TH09. TH04 usa un altro " +"compilatore dell’epoca DOS. La {ph0}ricostruzione del codice del " +"giocatore{ph1} richiedeva ipotesi diverse sugli schemi del sorgente e sul " +"collegamento del codice in un eseguibile. Lo stesso autore ci dà " +"un’aspettativa iniziale, ma ogni obiettivo indica se è applicabile. Un " +"modello specializzato dovrebbe imparare a distinguere questi contesti." + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "Dove dovrebbe essere archiviata questa esperienza?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"Prima di decidere di insegnare questi modelli attraverso l'addestramento dei" +" modelli, esaminerei la conoscenza che già conserviamo nel repository. Nel " +"{ph0}saggio precedente{ph1} ho scritto che diventa la memoria di lavoro del " +"progetto. Quella memoria include lezioni del compilatore, insieme alla fonte" +" e agli esperimenti falliti che li hanno resi utili." + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"Recuperando quel record, un agente può iniziare con un risultato noto e " +"verificare come lo abbiamo raggiunto. Può anche evitare alternative che " +"hanno già fallito nello stesso contesto. Il punto di partenza migliora senza" +" modificare i parametri addestrati del modello." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"Durante la ricostruzione della funzione di TH09 per la creazione di nemici, " +"una sessione {ph0}GPT-6-Luna-max{ph1} ha preso un'ipotesi dal relativo " +"codice sorgente TH08. Il codice precedente suggeriva come organizzare il " +"ciclo e gestire gli errori al suo interno. Le prove di TH09 hanno fornito i " +"dettagli specifici del gioco. Le ricostruzioni dall'origine hanno confermato" +" che la funzione completa corrispondeva." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}\"Il modello non conosceva quella stranezza del compilatore\" e \"il " +"modello non poteva usarlo\" sono problemi diversi.{ph1} Il recupero può " +"risolvere il primo, ma trasformare questo fatto in un candidato utile " +"richiede ancora lavoro. E se il codice sorgente candidato fallisce, il " +"modello deve decidere cosa significherà il risultato per il suo prossimo " +"tentativo. Conoscere il modello rilevante è solo l’inizio di quel processo." + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"Per questo motivo, includerei in ogni confronto un modello di intelligenza " +"artificiale generico più piccolo con un buon recupero. Fornire la stessa " +"libreria di esperienze ci aiuterebbe a identificare ciò che la formazione " +"aggiunge: una migliore generazione di candidati, decisioni migliori dopo il " +"feedback o entrambi." + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "Imparare il prossimo esperimento utile" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"Quelle decisioni dopo il feedback sono ciò che mi piacerebbe di più " +"studiare. Nella ricostruzione agentica, il modello propone una spiegazione e" +" la mette alla prova rispetto al programma. Anche quando il codice sorgente " +"candidato fallisce, il risultato può restringere le possibilità rimanenti e " +"suggerire un prossimo esperimento più utile." + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "" +"Consideriamo nuovamente l'esempio dei risultati temporanei. La sua fonte " +"finale mostra la soluzione che ha funzionato, ma il percorso verso quella " +"fonte contiene più informazioni. Ciascuno dei seguenti esperimenti ha " +"contribuito a identificare ciò che ancora doveva cambiare." + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "Esperimento" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "Cosa ci ha insegnato il suo risultato" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "Prova un modo diverso per copiare i risultati" + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "Il codice di copia cambia, ma la funzione cambia ancora." + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "Utilizzare direttamente i valori restituiti" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "" +"La copia segue lo schema originale, ma l'archiviazione temporanea differisce" +" ancora." + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "Mantieni valide tutte le variabili temporanee contemporaneamente" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "" +"Ottengono un'archiviazione separata, ma uno si sovrappone comunque a un " +"valore utilizzato successivamente per i controlli di collisione." + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "Mantenere separato il valore del controllo collisioni" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "" +"Una ricompilazione pulita dalla fonte conferma la corrispondenza completa." + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "" +"Esperimenti selezionati dalla ricostruzione della funzione di attacco sopra," +" raggruppati in base a ciò che ci hanno insegnato." + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"Un registro dell'addestramento che mantenga questa sequenza può insegnare " +"più della sola fonte finale. Collega ogni modifica proposta a un risultato " +"osservato e alla decisione successiva. Anche mantenere le variazioni " +"inefficaci è importante: dicono a un agente successivo quali ipotesi sono " +"già state testate in quel contesto." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}Vorrei che il modello imparasse come utilizzare il feedback.{ph1} Un " +"risultato neutro è un motivo per riconsiderare la variazione; una mancata " +"corrispondenza modificata può indicare un'altra causa. Quando le modifiche " +"locali smettono di essere informative, l'agente dovrebbe essere in grado di " +"rivisitare la rappresentazione originale o ispezionare nuovamente le prove." + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"Imparare a fare queste scelte richiede autonomia. A volte il passaggio " +"successivo utile è ispezionare un altro chiamante anziché compilare un'altra" +" modifica. Una rigida sequenza di riscritture richieste eliminerebbe quella " +"scelta, insieme a parte del comportamento che vogliamo che il modello " +"impari." + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "" +"Perché il reverse engineering è interessante per l'apprendimento per " +"rinforzo" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"La ricostruzione limitata ci offre un ambiente pratico per studiare queste " +"scelte. Una volta fissate le versioni di destinazione e del compilatore, " +"molti esperimenti di origine producono un feedback rapido e ripetibile. " +"L'agente può compilare un candidato, ispezionare la mancata corrispondenza e" +" utilizzare tale osservazione per scegliere il passaggio successivo." + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"L’apprendimento per rinforzo potrebbe addestrare il processo decisionale " +"attraverso il feedback che riceve. Un candidato accettato con una verifica " +"definita ci dà un risultato concreto, mentre la sequenza dei tentativi ci " +"permette di osservare quanto lavoro è stato necessario per raggiungerlo." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"Esistono già ricerche a sostegno di questa direzione. " +"{ph0}LLM4Decompile{ph1} studia modelli specializzati per la decompilazione. " +"{ph2}AutoDecompiler{ph3} addestra il perfezionamento multi-turn utilizzando " +"il feedback del compilatore e dell'esecuzione. I loro studi si concentrano " +"sul recupero funzionale. Per questo lavoro, li userei come punto di partenza" +" per il compito correlato di trovare fonti che corrispondano all'output di " +"un compilatore storico." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"Per raggiungere un compito così ben definito, tuttavia, potremmo prima dover" +" stabilire quali risorse possiede una funzione o ideare un nuovo modo di " +"osservare il comportamento del programma durante l’esecuzione. In TH08, ad " +"esempio, una {ph0}differenza di collisione riportava al modo in cui il " +"programma originale gestiva i calcoli in virgola mobile{ph1}. Prima che " +"l'agente potesse testare una correzione utile, doveva capire cosa misurare." + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "" +"Ciò suggerisce un altro ruolo per un modello ampiamente capace: in primo " +"luogo, contribuire a rendere il problema controllabile. Una volta effettuato" +" questo controllo, possiamo indagare fino a che punto può arrivare una " +"politica di ricerca appresa." + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "Quando il controllo di verifica è sbagliato" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"Quando una verifica viene usata per l’addestramento, anche la sua copertura " +"entra nell’ambiente di apprendimento. Chiamo oracle quel riferimento o " +"verificatore. Persino una risposta ripetibile va interpretata in base a ciò " +"che verifica davvero." + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"TH08 ha mostrato quanto si può nascondere al di fuori di quella copertura. " +"Alcune funzioni ricostruite hanno superato i confronti esatti con costanti " +"in virgola mobile errate. Il comparatore aggiustava gli indirizzi trasferiti" +" prima di controllare le istruzioni, ma controllava i valori dietro quegli " +"indirizzi solo quando erano stati esplicitamente registrati per la verifica." +" Altri riferimenti letterali potrebbero passare senza che i loro valori " +"vengano esaminati." + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"Per colmare questa lacuna, un {ph0}controllo più ampio{ph1} ha rilevato " +"costanti errate nelle funzioni che avevano già superato la verifica. In un " +"calcolo, il codice sorgente ricostruito aggiungeva {ph2}, mentre l'originale" +" aggiungeva {ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}Un modello premiato dal vecchio controllo di verifica potrebbe imparare" +" a produrre una ricostruzione errata.{ph1} Non abbiamo addestrato un modello" +" RL utilizzando quel controllo. L'errore che abbiamo osservato riguardava il" +" controllo stesso. Ma se lo usassimo come ricompensa, lo stesso punto cieco " +"diventerebbe parte dell’ambiente di apprendimento." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"Un test funzionale può avere un punto cieco simile. {ph0}La ricerca che " +"utilizza il fuzzing differenziale sui decompilatori LLM{ph1} ha rilevato " +"differenze comportamentali al di fuori dei test forniti. Dobbiamo quindi " +"comprendere una prova di superamento in termini dei casi che esercita. Allo " +"stesso modo, la corrispondenza di un'istruzione deve essere intesa in " +"termini di byte e dati che verifica." + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"Prima di utilizzare uno dei due tipi di controllo di verifica come " +"ricompensa, lo testerei con risultati deliberatamente errati. Vorrei anche " +"mantenere l'accettazione finale separata dal codice sorgente che l'agente AI" +" può modificare. Il modello deve superare la verifica ricostruendo " +"correttamente il programma. Altrimenti, la semplice copia di un array di " +"byte dalla destinazione potrebbe ingannare un ingenuo sistema di punteggio " +"senza recuperare codice sorgente utile." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "" +"{ph0}Migliorare lo studente e migliorare il suo strumento di verifica " +"appartengono allo stesso problema di ricerca.{ph1} Man mano che lo studente " +"migliora nell'ottimizzare il feedback che gli forniamo, anche comprendere " +"quel feedback diventa più importante." + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "Un confronto che vale la pena fare" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"Con questi controlli in atto, inizierei il confronto su una famiglia di " +"attività VC7.1 fissa. Innanzitutto, stabilirei le linee di base per un forte" +" modello di intelligenza artificiale generale e uno più piccolo. L'aggiunta " +"della conoscenza del repository al modello più piccolo mostrerebbe quali " +"cambiamenti nel recupero. Da lì, la specializzazione supervisionata e una " +"versione addestrata con RL ci permetterebbero di esaminare cosa aggiunge la " +"formazione." + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"Per rendere informativi questi confronti, ciascun modello riceverebbe le " +"stesse prove e strumenti target. Per i confronti specifici della formazione," +" manterrei fisso anche il modello base e le conoscenze disponibili. Prove " +"ripetute aiuterebbero a distinguere una strategia di ricerca affidabile da " +"una soluzione candidata che ha successo per caso." + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"Separerei quindi due condizioni iniziali: ricostruire una funzione dalle sue" +" istruzioni e chiudere le ultime differenze nel sorgente mantenuto. Un " +"modello di IA specializzato potrebbe essere eccellente per il secondo " +"compito, mentre un modello di IA generico svolge gran parte del lavoro " +"necessario per raggiungerlo. Misurarli separatamente rivelerebbe quella " +"divisione del lavoro." + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"Entrambi i compiti necessitano di esempi di test esclusi dall'addestramento " +"e dal recupero. I giochi Touhou correlati condividono il codice motore. " +"Escludere un gioco dall'allenamento potrebbe comunque lasciare funzioni " +"quasi identiche nel set di allenamento. Invece, escluderei interi gruppi di " +"codice sorgente correlato e manterrei le loro risposte verificate fuori sia " +"dai dati di addestramento che dalla libreria di recupero." + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"Per questi esempi, il risultato sarebbe corrispondenze complete e verificate" +" in modo indipendente. Budget uguali per le proposte dei candidati o i " +"tentativi di compilazione aiuterebbero a confrontare la qualità della " +"ricerca. La misurazione del tempo e dei costi totali, inclusa la " +"compilazione, mostrerebbe se tale qualità produce un flusso di lavoro " +"efficiente. I costi di formazione dovrebbero essere misurati separatamente." + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"Entrambe le misurazioni contano. Una proposta economica può portare a un " +"flusso di lavoro costoso se comporta più compilazioni che non forniscono " +"informazioni utili. Al contrario, un modello più lento può essere più " +"economico se trova prima un esperimento utile. Il confronto dovrebbe " +"includere questi costi." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"Il conteggio dei risultati accettati mantiene inoltre in prospettiva i " +"progressi intermedi. Un TH09 {ph0}candidato al replay-save{ph1} sembrava " +"promettente perché la funzione compilata aveva le dimensioni previste, ma un" +" confronto completo ha comunque rilevato differenze sostanziali. I " +"cambiamenti nel modo in cui il compilatore organizza le istruzioni possono " +"anche far sembrare un candidato più vicino al risultato atteso senza " +"risolvere il problema di fondo. Tale diagnostica può guidare il prossimo " +"esperimento, ma convaliderei qualsiasi ricompensa per \"avvicinarsi\" " +"rispetto al controllo completo di accettazione." + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"Sarei interessato allo schema tra questi risultati. Se un modello di " +"intelligenza artificiale specializzato funziona bene all’interno di una " +"famiglia di compilatori familiare, tale vantaggio sopravvive a un " +"cambiamento nella toolchain? E una volta che entrambi i modelli di " +"intelligenza artificiale hanno un buon recupero, quanto aggiunge ancora " +"l’addestramento? Le risposte ci aiuterebbero a decidere dove ciascun tipo di" +" modello è più utile." + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "Che tipo di agente AI suggerisce questo?" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"Se i modelli si rivelano utili in diverse fasi, una soluzione utile potrebbe" +" essere un ampio agente con accesso a un modello di intelligenza artificiale" +" specializzato. Una volta che un'attività diventa una ricerca familiare del " +"compilatore, potrebbe richiedere il modello di intelligenza artificiale " +"specializzato per i candidati. Se i risultati smettono di avere senso, " +"l’agente più ampio potrebbe tornare all’evidenza target o indagare sulla " +"misurazione stessa." + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "" +"In questo modo, la specializzazione diventa uno strumento che l’agente può " +"scegliere man mano che l’indagine si sviluppa. L'agente mantiene la libertà " +"di cambiare direzione che ha reso possibili i progressi precedenti." + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"Ciò deriva naturalmente dal cambiamento industriale che ho descritto nel " +"saggio precedente. Essere in grado di eseguire molti più esperimenti cambia " +"il modo in cui organizziamo il lavoro. Ci dà anche una ragione per chiederci" +" quali decisioni necessitano di un ampio giudizio e quali migliorano " +"attraverso l’esperienza ripetuta con una particolare imbarcazione." + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"Per ora il modello generale più forte si è guadagnato il suo posto nel mio " +"lavoro risolvendo problemi che avevo lasciato aperti. Sono proprio questi " +"successi a farmi studiare il processo: quanto dipendeva dall’ampiezza delle " +"sue capacità, e quanto potrebbe fare un modello addestrato specificamente " +"per questo tipo di ricostruzione?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "" +"{ph0}I repository ci offrono un modo per testare la domanda.{ph1} Vorrei " +"utilizzare quel record per creare il confronto e vedere cosa impariamo." + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "Evidenze e attribuzione del modello" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"Gli esempi descrivono i confronti storici a livello di funzione registrati " +"nei commit collegati. I controlli di runtime dell'intero gioco sono " +"traguardi separati. I record di origine e corrispondenza sono stati " +"esaminati il 13 ottobre 2026." + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"L'etichetta TH09 {ph0} significa GPT-6-Astra. Il modello associato a {ph1} è" +" cambiato nel tempo, quindi l'etichetta da sola non può identificare il " +"modello utilizzato in una specifica esecuzione. I nomi espliciti dei modelli" +" negli altri commit citati forniscono l'attribuzione registrata. Queste " +"cronologie non includono misurazioni coerenti dei costi o dell'impegno per " +"ogni esecuzione." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "" +"{ph0}TH09 durata degli oggetti temporanei:{ph1} la {ph2}revisione del " +"contesto precedente{ph3} e la {ph4}ricostruzione completa verificata da una " +"ricompilazione pulita dall'origine{ph5}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"{ph0}TH09 Front callback:{ph1} {ph2}aree diagnostiche che non " +"corrispondevano{ph3}, il nuovo grafico del flusso di controllo di " +"{ph4}Astra{ph5} e il relativo {ph6}controllo di ricompilazione " +"accettato{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}Conoscenze del compilatore:{ph1} {ph2}TH095 riutilizzo del " +"comportamento del bucket di identificatori{ph3}, {ph4}TH04 codice sorgente " +"del giocatore e ordine dei linker{ph5} e {ph6}Luna ricostruzione completa " +"della funzione di creazione del nemico di TH09{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}Controlli e diagnostica:{ph1} {ph2}TH08 audit costante in virgola " +"mobile{ph3}, {ph4}TH08 indagine numerica{ph5} e {ph6}TH09 ricostruzione con " +"salvataggio replay{ph7}." + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "" +"I confronti proposti tra modelli specializzati e la formazione RL sono " +"esperimenti futuri. Le storie dei progetti li motivano. Per questo saggio " +"non è stato valutato alcun modello specializzato addestrato." + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "Il reverse engineering necessita di un modello più grande? | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "" +"Cosa mi ha insegnato la ricostruzione Touhou sui modelli generali, sui " +"modelli specialistici e sull'imparare a proporre ipotesi migliori dal " +"feedback del compilatore." + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "In questa pagina" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "Modelli e saggio di reverse engineering" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "Esperimenti di ricostruzione selezionati" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "Torna in alto" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "" +"Le {ph0}note dettagliate sulle prove{ph1} includono i confronti registrati e" +" il contesto degli esperimenti." + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "Di N0zoM1z0 · 13 ottobre 2026 · Bozza da rivedere" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "Guida all’installazione" diff --git a/website/locales/ja/messages.po b/website/locales/ja/messages.po index 10ed8ee27..17d784abd 100644 --- a/website/locales/ja/messages.po +++ b/website/locales/ja/messages.po @@ -32,18 +32,18 @@ msgid "Thoughts on reverse engineering." msgstr "リバースエンジニアリングに関する考え。" #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "ゲーム再構築{ph0}小論文" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "リバースエンジニアリングにおける産業革命" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " @@ -51,19 +51,20 @@ msgid "" msgstr "" "どのようなマニュアル再とTH08を再構築,TH095とTH04は、エージェントについて教えてくれました,プロジェクト間で化合物の検証と知識." -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "記事を読む" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "によってN0zoM1z0•10 10月2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -97,6 +98,8 @@ msgid "" msgstr "REAとAIエージェントの実践的な経験に基づいて、リバースエンジニアリングに関する考え。" #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -131,6 +134,7 @@ msgid "" msgstr "REA—ソフトウェアがどのように動作するかを調べます。 コーディングエージェントとのリバースエンジニアリング。" #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -151,6 +155,7 @@ msgid "REA home" msgstr "REA ホーム" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -171,6 +176,7 @@ msgid "Main navigation" msgstr "メインナビゲーション" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -191,6 +197,7 @@ msgid "REA on GitHub" msgstr "GitHub で REA を見る" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -211,6 +218,7 @@ msgid "Join REA on Discord" msgstr "REA の Discord に参加" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -230,7 +238,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "X で REA をフォロー" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "ページ上部へ" @@ -10886,6 +10894,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "同じ間隔:256÷16=16角度単位=22.5°" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -10906,6 +10915,7 @@ msgid "Showcases" msgstr "事例" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -10926,6 +10936,7 @@ msgid "Blog" msgstr "ブログ" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -10946,6 +10957,7 @@ msgid "Get started" msgstr "はじめる" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -10965,7 +10977,8 @@ msgctxt "shared" msgid "Guides" msgstr "ガイド" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -10985,7 +10998,8 @@ msgctxt "shared" msgid "Source" msgstr "ソースコード" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -11005,7 +11019,8 @@ msgctxt "shared" msgid "MIT license" msgstr "MIT ライセンス" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -11025,7 +11040,8 @@ msgctxt "shared" msgid "Join the community" msgstr "コミュニティに参加" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -11963,6 +11979,1171 @@ msgstr "" "キャプチャ、MCP、公開スキル{ph1}を利用してください。SAZ ??? HAR 1.2 をエクスポートすれば REA でオフラインのキャプチャ " "Evidence を取得できます。また、Everywhere の MCP サーバーを接続して、エージェントと一緒に記録済みの通信を調べることもできます。" +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "モデルの特化{ph0}エッセイ" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "リバースエンジニアリングに、より大きなモデルは必要か?" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "Touhou の再構築を通じて考える、汎用モデル、特化モデル、そしてコンパイラのフィードバックから学ぶ方法。" + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "N0zoM1z0 著 · 2026 年 10 月 13 日" + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "コンテンツにスキップ" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "{ph0}ホーム{ph1} / {ph2}ブログ{ph3} / モデルとリバース エンジニアリング" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "エッセイ" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "リバースエンジニアリングに、より大きなモデルは必要か?" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "N0zoM1z0 著 · 2026 年 10 月 13 日" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "要点" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "" +"{ph0}モデルの能力によって、エージェントが見つけられる仮説は変わる。{ph1} 後の作業では、それまで解決できなかった問題が解決された。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "" +"{ph0}使い慣れたコンパイラには、特化モデルが学べる具体的なパターンがある。{ph1} " +"完全一致の中には、細かな、再利用可能なソースコードのパターンに依存するものもある。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "" +"{ph0}リポジトリに蓄積した知識も、公平に比較したい。{ph1} 小さなモデルでも、適切に知識を検索できれば、作業を進めるのに十分かもしれない。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "" +"{ph0}次の有用な実験を選ぶ力を学習させ、その検証器も確かめる。{ph1} フィードバックの価値は、検証器が実際に何を確認しているかで決まる。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "" +"{ph0}検証を通った再構築の成果を、時間とコストと合わせて評価する。{ph1} エージェントのワークフロー全体で測りたいのは、その結果だ。" + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "この記事の内容" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}強いモデルで何が変わったか{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}なぜ特化を考えるのか{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}その経験はどこに蓄積すべきか?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}次の有用な実験を選ぶ力を学ぶ{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}リバース エンジニアリングと強化学習{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}検証器が間違っていたら{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}実行する価値のある比較{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}どんなエージェントが必要なのか?{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "強いモデルで何が変わったか" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"2026年8月から、プログラムにアクセスし、自分の作業を検証できるエージェントが、どこまでリバースエンジニアリングを進められるかを探ってきた。私の経験は主にゲーム、特に" +" Touhou(東方)の再構築から得たものだ。モデルを変えるたびに、各セッションで何を復元できたかがリポジトリに残った。" + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"その多くは完全一致を目指す再構築だ。バージョンを固定した当時のツールチェーンで、保守しているソースをコンパイルし、対象の関数を再現できるか確かめる。後のモデルが以前の行き詰まりを解消したとき、ソースの変更を見ると、何が進歩を可能にしたかがわかる。" + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "一時的な値を同時に有効にしておく必要があった" + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"TH09 " +"のある攻撃関数は、ロジックの大部分が復元済みだった。それでも、コンパイラが一時的な結果を格納する方法は原版と違っていた。残る問題は、その結果がいつまで有効であるべきか、そして格納領域をいつ再利用できるかだった。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"いくつかの通常のソースコード配置をテストした後、{ph0}GPT-6-Sol セッション レコード{ph1} でこの不一致が報告されました。 " +"{ph2}GPT-6.1-Sol がこの問題を再度調査したとき{ph3}、これらの一時変数の存続期間に関する有用な仮説が提案されました。" + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"この関数は一時的な結果を作り、アニメーションの位置にコピーする。C++ " +"の一時的な結果は、それを使う式が終わるまで生存する。実際の処理を一つの式にまとめると、結果の生存期間が重なり、コンパイラはすべての結果に同じ格納領域を使い回せなくなる。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"一つの結果だけは、後の衝突判定に使う値と領域を共有していた。その値に独立した生存期間を与えると、最後の重なりも解消された。いくつかの絞り込んだ実験の後、{ph0}クリーンビルドで関数全体の一致が確認された{ph1}。" + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"発見とテストがどのように相互にサポートし合っていたのかに興味があります。一時オブジェクトの存続期間に関する仮説は、AI " +"エージェントに新しい方向性を与えました。コンパイラーからのフィードバックにより、その仮説を改良して、一致するソースコードの配置を実現することができました。" + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "別の制御フロー グラフ" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"2 番目の TH09 関数は、その新しい方向が重要である理由を示しています。ここでの障害は、複数のブランチが最終的な作業をどのように共有するかでした。 " +"{ph0}GPT-6.1-Sol の以前の作業{ph1} " +"では、関数の一部が一致していましたが、分岐の結合方法は依然としてオリジナルとは異なっていました。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}GPT-6-Astra が周囲の制御フロー グラフを変更しました{ph1}。メイン " +"パスは共有された最終更新と復帰につながりました。そのソース構造では、コンパイラはオリジナルと同じ方法でブランチを結合しました。完全な関数は一致しており、{ph2}別のリビルド" +" チェックでそれが確認されました{ph3}。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}表現を変えたことで、より有望な探索空間が開けた。{ph1} " +"この二つの例から、汎用モデルの能力は重要だと感じる。エージェントは局所的な変更を長く試した末に、周囲の処理を表すもっとよい方法を見つけることがある。" + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"ただし、後のセッションは、それまでのソースと失敗の記録を引き継いでいる。その蓄積も有利に働いた。履歴から発見と検証の過程は調べられるが、モデルの効果と引き継いだ経験の効果を分けるには、条件をそろえた比較が必要だ。" + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"これが私にとってこの質問が興味深い理由です。新しい表現を見つけることである程度の進歩が得られました。残りの作業の多くには、使い慣れたコンパイラに対してさまざまなソース" +" " +"コードの配置をテストすることが含まれていました。このうちどの程度の範囲で幅広い推論能力が必要でしょうか?モデルはそのコンパイラーとコードを繰り返し操作することでどれだけ学習できるでしょうか?" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "特化モデルがうまく働く可能性は?" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"Touhou には、経験の蓄積が役立つと考える具体的な理由がある。多くのゲームコードを ZUN " +"一人が書いているため、繰り返し現れる書き方を最初の仮説にできる。実際、リポジトリには、似たループや補助関数の構成が別のゲームの仮説につながった例がある。" + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "" +"コンパイラを含めると、これらのソース " +"パターンがより具体的になります。特定のバージョンとオプションのセットでは、ソースに小さな変更を加えると、マシンコードに再現性のある差異が生じる可能性があります。これらの違いの中には、驚くほどわかりにくいものもあります。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"たとえば、TH095 では、{ph0}ローカル変数の名前であっても、VC7.1 " +"がそれを格納する場所に影響を与える可能性があります{ph1}。その宣言を移動してもストレージ " +"レイアウトは解決されませんでした。ただし、以前のバックグラウンド関数では、コンパイラの選択に影響を与える名前付けパターンが明らかになっていました。これは、{ph2}{ph3}{ph4}" +" を再構築するためのより有望な仮説を示唆しました。" + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "そのパターンをファイルサイズの変数に使うと、格納領域を増やさずに必要な配置が得られた。続いて関数全体が一致した。" + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "" +"これは非常に具体的な詳細であり、汎用 AI " +"モデルが最初に問題に遭遇したときには認識できない可能性があります。このコンパイラに特化したモデルは、そのようなケースを多数確認し、どのソース " +"コードのバリエーションが最初にテストする価値があるかを学習できます。" + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"動作を理解したうえで最後の差分を詰める場面では、この可能性が特にはっきりする。問うのは、このコンパイラがどの通常の書き方を観測された命令に変換するかだ。特化した学習によって候補を効率よく出せるかもしれないが、どの仮説が正しいかは対象のプログラムが決める。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"ただし、パターンには適用条件を残す必要がある。TH08 は TH095 や TH09 より古い Visual C++ を使う。TH04 は DOS " +"時代の別のコンパイラを使い、{ph0}プレイヤーのコードの再構築{ph1}では、書き方や実行ファイルへのリンク順序について別の仮説が必要だった。同じ作者であることは手がかりになるが、適用できるかは各対象で確かめる。その区別も特化モデルが学ぶべきことだ。" + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "その経験はどこに蓄積すべきか?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"モデルの学習でこうしたパターンを覚えさせる前に、まずリポジトリに保存している知識を見たい。{ph0}前のエッセイ{ph1}では、リポジトリがプロジェクトの作業記憶になっていると書いた。そこにはコンパイラから学んだことと、それを裏付けるソースや失敗した実験が残っている。" + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"そのレコードを取得することで、エージェントは既知の結果から開始し、どのようにしてその結果に到達したかを検査できます。また、同じコンテキストですでに失敗した代替案を回避することもできます。モデルのトレーニング済みパラメーターを変更することなく、開始点が改善されます。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"TH09 の敵生成関数を再構築した{ph0}GPT-6-Luna-max のセッション{ph1}は、TH08 " +"の関連するソースから仮説を得た。以前のコードが、ループの構成と失敗時の処理の手がかりになった。TH09 " +"自体の証拠でゲーム固有の細部を補い、クリーンビルドで関数全体の一致を確認した。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}「モデルがそのコンパイラの癖を知らない」と「知っていても使えない」は別の問題だ。{ph1} " +"検索で前者を解決できても、知識を有用な候補にするには能力がいる。候補が失敗すれば、その結果が次の試みに何を意味するかも判断しなければならない。関連するパターンを知るのは、出発点にすぎない。" + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"だから比較には、知識を適切に検索できる小さな汎用モデルも加えたい。同じ経験のライブラリを与えれば、学習が何を加えるかを調べられる。候補を作る力なのか、フィードバック後の判断なのか、それとも両方なのか。" + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "次の有用な実験を選ぶ力を学ぶ" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"私が最も研究したいのは、フィードバック後の判断だ。エージェントによる再構築では、モデルが説明を提案し、プログラムに照らして検証する。候補が失敗しても、可能性を絞り、次の有用な実験を考える材料になる。" + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "" +"一時的な結果の例をもう一度考えてみましょう。最終的なソースには、機能した配置が示されていますが、そのソースへのルートにはさらに多くの情報が含まれています。以下の各実験は、まだ変更する必要があるものを特定するのに役立ちました。" + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "実験" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "その結果が私たちに教えてくれたこと" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "別の方法で結果をコピーしてみてください" + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "コピーのコードは変わったが、関数にはまだ差分がある。" + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "戻り値を直接使用する" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "コピーは元のパターンに従いますが、一時ストレージは依然として異なります。" + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "一時的な結果を同時に有効にしておく" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "これらは別々のストレージを取得しますが、1 つは、後で衝突チェックに使用される値と依然として重複します。" + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "衝突判定の値を独立させる" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "ソースからクリーンに再コンパイルすると、完全に一致していることが確認されます。" + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "上記の攻撃関数の再構築から選択した実験を、教えられた内容ごとにグループ化しました。" + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"この順序を維持したトレーニング記録は、最終的なソースだけよりも多くのことを教えることができます。提案された各変更を観察された結果と次の決定に結び付けます。効果のないバリエーションを維持することも重要です。バリエーションは、後のエージェントに、そのコンテキストでどの仮説がすでにテストされているかを伝えます。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}モデルにはフィードバックの使い方を学んでほしい。{ph1} " +"結果が変わらなければ、その変更を考え直す理由になる。差分が変われば、別の原因が見えてくるかもしれない。局所的な編集から情報が得られなくなったら、全体の書き方を見直したり、証拠を再確認したりできるべきだ。" + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"これらの選択を行うことを学ぶには自主性が必要です。場合によっては、別の編集をコンパイルするのではなく、別の呼び出し元を検査することが次のステップとして役立つ場合があります。必要な書き換えを厳密に繰り返すと、モデルに学習させたい動作の一部とともに、その選択肢が削除されてしまいます。" + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "リバースエンジニアリングが強化学習にとって興味深い理由" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"範囲を定めた再構築は、こうした判断を研究するための実用的な環境になる。対象とコンパイラのバージョンを固定すれば、多くのソースの実験で素早く再現可能なフィードバックを得られる。エージェントは候補をコンパイルし、差分を調べ、次の行動を選べる。" + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"強化学習なら、得られたフィードバックからこの判断を学習できるかもしれない。定義された検証を通った候補は具体的な成果になり、試行の記録から、そこに至るまでの労力も調べられる。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"この方向を支える研究はすでにある。{ph0}LLM4Decompile{ph1}は逆コンパイルに特化したモデルを研究している。{ph2}AutoDecompiler{ph3}はコンパイルと実行のフィードバックを使って複数ターンの改善を学習する。両者が扱うのは機能の復元だ。私はそこを出発点に、当時のコンパイラの出力に一致するソースを探すという関連した課題を研究したい。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"ただし、このように明確に定義されたタスクに到達するには、まず関数が所有するリソースを確立するか、実行中のプログラムの状態や振る舞いを観測する新しい方法を考案する必要があるかもしれません。たとえば、TH08" +" " +"では、{ph0}衝突の違いにより、元のプログラムでの浮動小数点計算の処理方法が問題になりました{ph1}。エージェントが有用な補正をテストする前に、何を測定するかを決定する必要がありました。" + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "" +"ここから、幅広い能力を持つモデルのもう一つの役割が見える。まず問題を検証可能にすることだ。検証方法ができて初めて、学習した探索方針がどこまで進めるかを調べられる。" + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "検証器が間違っていたら" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"その検証を使って学習すると、検証範囲も学習環境の一部になる。私はこうした参照基準や検証器を oracle " +"と呼んでいる。答えが再現可能でも、それが何を確認した答えなのかを理解する必要がある。" + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"TH08 " +"では、検証範囲の外に問題が隠れていた。誤った浮動小数点定数を使っていても、完全一致の比較を通る関数があった。比較器は命令を確認する前に再配置されたアドレスを調整するが、そのアドレスが指す値まで確認するのは、検証対象として明示的に登録された場合だけだった。ほかの定数への参照は、値を調べずに通ってしまう可能性があった。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"このギャップに対処するために、{ph0}広範な監査{ph1}により、すでに検証に合格した関数内に不正な定数が見つかりました。ある計算では、再構成されたソース" +" コードでは {ph2} が追加されましたが、元のコードでは {ph3} が追加されました。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}古い検証結果で報酬を与えれば、モデルは誤った再構築を学習してしまうかもしれない。{ph1} この検証器で RL " +"モデルを訓練したわけではない。観測したのは検証そのものの不具合だ。ただ、それを報酬に使えば、同じ盲点が学習環境に入ることになる。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"機能テストにも同様の盲点がある可能性があります。 {ph0}LLM " +"デコンパイラで差分ファジングを使用した研究{ph1}では、提供されたテスト以外の動作の違いが見つかりました。したがって、合格したテストを、実行されるケースの観点から理解する必要があります。同様に、命令の一致は、検証されるバイトとデータの観点から理解する必要があります。" + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"どちらの種類の検証チェックも報酬として使用する前に、意図的に間違った結果でテストします。また、最終的な承認は、AI エージェントが編集できるソース " +"コードとは別にしておきます。モデルはプログラムを正しく再構築することで検証に合格する必要があります。そうしないと、ターゲットからバイト配列をコピーするだけで、有用なソース" +" コードを回復せずに、単純なスコアリング システムを騙してしまう可能性があります。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "" +"{ph0}学習するモデルの改善と、その検証器の改善は同じ研究課題だ。{ph1} " +"モデルが与えられたフィードバックを上手に最適化するほど、そのフィードバックを理解することも重要になる。" + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "実行する価値のある比較" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"これらのチェックを実施したら、固定の VC7.1 タスク ファミリで比較を開始します。まず、強力な汎用 AI モデルと小規模な AI " +"モデルのベースラインを確立します。リポジトリの知識をより小さなモデルに追加すると、取得によってどのような変化が生じるのかがわかります。そこから、教師付き特殊化と" +" RL でトレーニングされたバージョンを使用して、トレーニングによって追加される内容を検証できるようになります。" + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"これらの比較を有益なものにするために、各モデルは同じターゲットの証拠とツールを受け取ります。トレーニング固有の比較の場合、基本モデルと利用可能な知識も固定したままにします。試行を繰り返すことは、信頼できる検索戦略と偶然成功した候補ソリューションを区別するのに役立ちます。" + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"二つの出発点も分けたい。命令から関数を再構築する場合と、保守しているソースの最後の差分を詰める場合だ。特化モデルが後者に優れていても、そこまでの作業の多くは汎用モデルが担っているかもしれない。別々に測れば、その分担が見える。" + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"どちらのタスクも、トレーニングと取得から除外されたテスト例が必要です。関連する Touhou ゲームはエンジン コードを共有します。トレーニングから 1" +" つのゲームを除外しても、トレーニング セットにほぼ同じ機能が残る可能性があります。代わりに、関連するソース " +"コードのグループ全体を除外し、検証済みの回答をトレーニング データと検索ライブラリの両方から除外します。" + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"測る成果は、関数全体が独立した検証を通って一致したことだ。候補数やコンパイル回数の予算をそろえれば探索の質を比べられる。コンパイルを含む総時間と総費用を測れば、それが効率的なワークフローにつながるかがわかる。学習費用は別に計上したい。" + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"どちらの測定値も重要です。安価な提案により、有用な情報を提供しないコンパイルが増加すると、ワークフローが高価になる可能性があります。逆に、有用な実験がすぐに見つかった場合、遅いモデルの方が経済的になる可能性があります。比較にはこれらのコストも含める必要があります。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"受け入れられた結果をカウントすることで、中間の進捗状況も把握できます。 1 つの TH09 " +"{ph0}再生保存候補{ph1}は、コンパイルされた関数が予想どおりのサイズを持っていたため有望に見えましたが、完全な比較では依然として大きな違いが見つかりました。コンパイラが命令を配置する方法を変更すると、根本的な問題が解決されずに、候補がより近くに見える可能性もあります。このような診断は次の実験を導くことができますが、私は「近づく」ことに対する報酬を完全な受け入れチェックと照らし合わせて検証します。" + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"結果全体にどんな傾向があるかを知りたい。特化モデルが使い慣れたコンパイラで優れていても、ツールチェーンを変えた後にその強みは残るだろうか。両方が十分に知識を検索できるとき、学習はどれだけ価値を加えるのか。答えは、各モデルをどこで使うべきかを考える助けになる。" + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "どんなエージェントが必要なのか?" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"モデルが段階ごとに違う強みを持つなら、汎用エージェントが特化モデルを呼び出せる構成が役立つかもしれない。問題が慣れたコンパイラでの探索になったら、特化モデルに候補を求める。結果が納得できなくなったら、汎用エージェントが対象の証拠や測定そのものを調べ直す。" + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "この構成では、特化モデルは調査の進み方に応じて選べる道具になる。エージェントには、以前の突破口を可能にした方向転換の自由が残る。" + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"これは、前回のエッセイで説明した産業の変化から自然に生じます。さらに多くの実験を実行できるようになると、作業の組織化の方法が変わります。また、どの決定には広範な判断が必要なのか、どの決定は特定の技術での繰り返しの経験によって改善されるのかを尋ねる理由も得られます。" + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"今のところ、未解決のまま残されていた問題を解決することで、最強の汎用 AI " +"モデルが私のワークフローにその地位を獲得しました。これらの成功により、私はこの作業をさらに詳しく調べてみたいと思うようになりました。どの程度がモデルの範囲に依存しているのか、また、この特定の種類の再構成でトレーニングされたモデルでどの程度の処理が可能でしょうか?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "{ph0}リポジトリは、質問をテストする方法を提供します。{ph1}その記録を使用して比較を構築し、何が分かるかを確認したいと思います。" + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "証拠とモデルの帰属" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"この例では、リンクされたコミットに記録された関数レベルの比較の履歴について説明します。ゲーム全体のランタイム " +"チェックは別のマイルストーンです。ソースと一致する記録は 2026 年 10 月 13 日に確認されました。" + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"TH09 ラベル {ph0} は GPT-6-Astra を意味します。 {ph1} " +"に関連付けられたモデルは時間の経過とともに変化したため、ラベルだけでは特定の実行で使用されたモデルを識別できません。他の引用されたコミット内の明示的なモデル名は、記録された帰属を示します。これらの履歴には、実行ごとのコストや労力の一貫した測定値は含まれていません。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "" +"{ph0}TH09 一時オブジェクトの有効期間:{ph1} {ph2}以前のコンテキスト " +"レビュー{ph3}と、{ph4}ソースからのクリーンな再コンパイルによって検証された完全な再構築{ph5}。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"{ph0}TH09 Front コールバック:{ph1} {ph2}一致しなかった診断領域{ph3}、{ph4}Astra の新しい制御フロー " +"グラフ{ph5}、およびその {ph6}受け入れられた再コンパイル チェック{ph7}。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}コンパイラーの知識:{ph1} {ph2}TH095 識別子バケットの動作の再利用{ph3}、{ph4}TH04 プレーヤーのソース " +"コードとリンカーの順序{ph5}、および {ph6}Luna による TH09 の敵作成関数の完全な再構築{ph7}。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}チェックと診断:{ph1} {ph2}TH08 浮動小数点定数監査{ph3}、{ph4}TH08 数値調査{ph5}、および " +"{ph6}TH09 リプレイ保存再構築{ph7}。" + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "" +"特化モデルと RL " +"の比較は、これから行いたい実験だ。プロジェクトの履歴がその動機になっているが、このエッセイで学習済みの特化モデルを評価したわけではない。" + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "リバースエンジニアリングに、より大きなモデルは必要か? | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "Touhou の再構築から考える、汎用モデルと特化モデル、そしてコンパイラのフィードバックからよりよい仮説を学ぶ可能性。" + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "このページでは" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "モデルとリバース エンジニアリングのエッセイ" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "厳選された復元実験" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "ページ上部へ" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "{ph0}詳しい証拠の記録{ph1}には、比較結果と実験の背景をまとめている。" + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "N0zoM1z0 著 · 2026年10月13日 · レビュー用草稿" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "セットアップガイド" diff --git a/website/locales/ko/messages.po b/website/locales/ko/messages.po index efcf4a708..3d0354df4 100644 --- a/website/locales/ko/messages.po +++ b/website/locales/ko/messages.po @@ -32,37 +32,38 @@ msgid "Thoughts on reverse engineering." msgstr "리버스 엔지니어링에 대한 생각." #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "게임 재구성{ph0}에세이" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "리버스 엔지니어링의 산업 혁명" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " "agents, verification and knowledge that compounds across projects." msgstr "어떤 매뉴얼 다시고 재구성TH08,TH095및TH04에 대해 가르쳐 에이전트,검증 및 지는 화합물에 걸쳐 프로젝트입니다." -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "기사 읽기" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "여N0zoM1z0·10 월 2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -96,6 +97,8 @@ msgid "" msgstr "리버스 엔지니어링에 대한 생각,실제 경험을 바탕으로 REA 그리고 인공지능 요원들도" #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -130,6 +133,7 @@ msgid "" msgstr "REA -소프트웨어가 어떻게 작동하는지 알아보십시오. 코딩 에이전트로 리버스 엔지니어링." #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -150,6 +154,7 @@ msgid "REA home" msgstr "REA 홈" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -170,6 +175,7 @@ msgid "Main navigation" msgstr "주 메뉴" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -190,6 +196,7 @@ msgid "REA on GitHub" msgstr "GitHub에서 REA 보기" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -210,6 +217,7 @@ msgid "Join REA on Discord" msgstr "REA Discord 참여" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -229,7 +237,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "X에서 REA 팔로우" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "맨 위로" @@ -10852,6 +10860,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "같은 간격:256÷16=16 각도 단위=22.5°" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -10872,6 +10881,7 @@ msgid "Showcases" msgstr "사례" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -10892,6 +10902,7 @@ msgid "Blog" msgstr "블로그" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -10912,6 +10923,7 @@ msgid "Get started" msgstr "시작하기" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -10931,7 +10943,8 @@ msgctxt "shared" msgid "Guides" msgstr "가이드" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -10951,7 +10964,8 @@ msgctxt "shared" msgid "Source" msgstr "소스 코드" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -10971,7 +10985,8 @@ msgctxt "shared" msgid "MIT license" msgstr "MIT 라이선스" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -10991,7 +11006,8 @@ msgctxt "shared" msgid "Join the community" msgstr "커뮤니티 참여" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -11927,6 +11943,1222 @@ msgstr "" "사용하세요. SAZ ?? HAR 1.2로 내보내면 REA에서 오프라인 캡처 Evidence를 얻을 수 있으며, Everywhere의 " "MCP 서버를 연결하여 에이전트와 함께 캡처된 트래픽을 살펴볼 수도 있습니다." +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "전문 모델{ph0}에세이" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "리버스 엔지니어링에는 더 큰 모델이 필요할까?" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "Touhou 재구축 경험을 바탕으로 범용 모델, 전문 모델, 컴파일러 피드백을 통한 학습을 생각해 봅니다." + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "작성자: N0zoM1z0 · 2026년 10월 13일" + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "개인정보보호정책" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "{ph0}홈{ph1} / {ph2}블로그{ph3} / 모델 및 리버스 엔지니어링" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "에세이" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "리버스 엔지니어링에 더 큰 모델이 필요할까?" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "작성자: N0zoM1z0 · 2026년 10월 13일" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "핵심 요점" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "" +"{ph0}모델 기능은 AI 에이전트가 제안할 수 있는 가설에 영향을 미칩니다.{ph1} 이후 세션에서는 이전 작업에서 해결되지 않은 " +"문제를 해결했습니다." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "" +"{ph0}익숙한 컴파일러는 특화 모델이 학습할 수 있는 구체적인 패턴을 제공합니다.{ph1} 일부 정확한 기계 코드 일치는 재사용 가능한" +" 특정 소스 코드 패턴에 따라 달라집니다." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "" +"{ph0}공정한 비교에 저장소 지식을 포함합니다.{ph1} 지식 검색이 좋은 소규모 모델은 이미 진행하기에 충분한 정보를 가지고 있을 수" +" 있습니다." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "" +"{ph0}다음 유용한 실험을 선택하도록 모델을 훈련시키고 검증 검사기를 테스트합니다.{ph1} 피드백은 검사기가 올바른 것을 검증하는 " +"정도까지만 유용합니다." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "" +"{ph0}시간 및 비용과 함께 검증된 재구성 결과를 평가합니다.{ph1} 이것이 제가 전체 AI 에이전트 워크플로에 대해 측정하고 싶은 " +"것입니다." + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "이 기사 에서" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}더 강한 모델이 바꾼 것{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}전문화해야 하는 이유{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}이 경험은 어디에 저장되어야 합니까?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}다음 유용한 실험 학습{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}리버스 엔지니어링 및 강화 학습{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}검증체커가 잘못된 경우{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}실행할 가치가 있는 비교{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}어떤 에이전트가 필요할까?{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "더 강한 모델이 바꾼 것" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"2026년 8월부터, 프로그램에 접근하고 자신의 작업을 검증할 수 있는 에이전트가 리버스 엔지니어링을 얼마나 수행할 수 있는지 탐구해 " +"왔다. 내 경험은 주로 게임, 특히 Touhou 재구성에서 나온다. 모델을 바꿔 가며 작업하는 동안 저장소에는 각 세션이 무엇을 " +"복원했는지 기록이 쌓였다." + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"이 작업의 상당 부분은 정확한 재구성을 목표로 한다. 버전을 고정한 당시의 툴체인으로 유지 관리 중인 소스 코드를 컴파일하고, 대상 " +"함수가 재현되는지 확인한다. 이전에 막혔던 문제를 나중 모델이 해결하면, 소스 변경을 통해 무엇이 진전을 가능하게 했는지 살펴볼 수 " +"있다." + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "임시 변수에는 수명이 겹치는 것이 필요했습니다." + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"TH09 공격 함수의 논리 대부분은 이미 재구성되었지만 컴파일러는 여전히 원본과 다르게 임시 결과를 저장했습니다. 남은 문제는 해당 " +"결과를 유지하는 데 필요한 기간과 해당 저장소를 언제 재사용할 수 있는지였습니다." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"여러 가지 일반적인 소스 코드 배열을 테스트한 후 {ph0}GPT-6-Sol 세션 레코드{ph1}에서 이러한 불일치를 보고했습니다. " +"{ph2}GPT-6.1-Sol이 문제를 다시 조사했을 때{ph3} 이러한 임시 변수의 수명에 대한 유용한 가설을 제안했습니다." + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"이 함수는 임시 결과를 생성하고 이를 애니메이션 위치에 복사했습니다. C++에서 임시 결과는 이를 사용하는 표현식이 완료될 때까지 활성 " +"상태로 유지됩니다. 실제 작업을 하나의 표현식으로 그룹화하면 해당 결과가 함께 유지되므로 컴파일러는 더 이상 모든 작업에 대해 동일한 " +"저장소를 재사용할 수 없습니다." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"한 결과는 나중에 충돌 확인을 위해 사용되는 값으로 여전히 저장 공간을 공유합니다. 해당 값에 고유한 수명을 부여하면 나머지 중복이 " +"해결되었습니다. 여러 번의 대상 실험 후 {ph0}소스에서 깔끔하게 재컴파일하여 전체 함수가 {ph1}과 일치함을 확인했습니다." + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"나는 발견과 테스트가 어떻게 서로를 지원하는지에 관심이 있습니다. 임시 개체 수명에 대한 가설은 AI 에이전트에 새로운 방향을 " +"제시했습니다. 컴파일러 피드백은 해당 가설을 일치하는 소스 코드 배열로 구체화하는 데 도움이 되었습니다." + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "다른 제어 흐름 그래프" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"두 번째 TH09 함수는 새로운 방향이 중요한 이유를 보여줍니다. 여기서 장애물은 여러 지점이 최종 작업을 공유하는 방식이었습니다. " +"{ph0}GPT-6.1-Sol의 이전 작업{ph1}에서는 일치하는 함수의 일부를 얻었지만 분기는 여전히 원본과 다르게 결합되었습니다." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}GPT-6-Astra이 주변 제어 흐름 그래프{ph1}를 변경했습니다. 이제 주요 경로는 공유된 최종 업데이트 및 복귀로 " +"이어졌습니다. 해당 소스 구조에서 컴파일러는 원본과 동일한 방식으로 분기를 결합했습니다. 전체 함수이 일치했으며 {ph2}별도의 재구축 " +"검사를 통해 이를 확인했습니다{ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}표현을 변경하면 보다 생산적인 검색 공간이 열렸습니다.{ph1} 두 경우 모두 일반 모델 기능을 진지하게 받아들여야 하는 이유가" +" 됩니다. 에이전트는 주변 작업을 표현하는 더 나은 방법을 찾기 전에 오랫동안 지역 변형을 계속 시도할 수 있습니다." + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"다만 이후 세션은 이전 소스 코드와 실패 기록을 이어받았다. 그 축적도 이점의 일부였다. 이력에서 발견과 검증 과정을 확인할 수는 " +"있지만, 모델 자체의 효과와 물려받은 경험의 효과를 구분하려면 조건을 맞춘 비교가 필요하다." + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"이것이 나에게 그 질문을 흥미롭게 만드는 이유이다. 새로운 표현을 찾는 과정에서 약간의 진전이 있었습니다. 나머지 작업의 대부분은 익숙한" +" 컴파일러에 대해 다양한 소스 코드 배열을 테스트하는 것과 관련되었습니다. 이 중 얼마나 폭넓은 추론 능력이 필요한가요? 해당 컴파일러와" +" 코드를 반복적으로 사용하여 모델이 얼마나 학습할 수 있습니까?" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "특화된 AI 모델이 왜 좋은 성과를 낼 수 있을까요?" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"Touhou은 그 경험이 도움이 될 것으로 기대하는 구체적인 이유를 제공합니다. 대부분의 게임 코드는 동일한 작성자인 ZUN에서 " +"제공되므로 반복되는 습관은 합리적인 시작 가정입니다. 저장소는 유용한 예를 통해 이를 뒷받침합니다. 관련 루프 및 도우미 배열은 게임 " +"전반에 걸쳐 가설을 제공했습니다." + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "" +"이러한 소스 패턴은 컴파일러를 포함하면 더욱 구체적이 됩니다. 특정 버전 및 옵션 세트에서는 소스의 작은 변경으로 인해 기계어 코드에 " +"반복 가능한 차이가 발생할 수 있습니다. 이러한 차이점 중 일부는 놀라울 정도로 모호합니다." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"예를 들어 TH095에서는 {ph0}로컬 변수의 이름도 VC7.1이 변수를 저장한 위치에 영향을 미칠 수 있습니다{ph1}. 선언을 " +"이동해도 스토리지 레이아웃이 해결되지 않았습니다. 그러나 이전 백그라운드 함수에서는 컴파일러의 선택에 영향을 미치는 명명 패턴이 " +"드러났습니다. 이는 {ph2}{ph3}{ph4} 재구성에 대한 더 유망한 가설을 제시했습니다." + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "" +"파일 크기 변수에 해당 패턴을 재사용하면 저장소를 추가하지 않고도 필요한 레이아웃이 생성되었습니다. 그런 다음 전체 함수이 일치했습니다." + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "" +"이는 범용 AI 모델이 처음 문제에 직면했을 때 알 수 없는 매우 구체적인 세부 사항입니다. 이 컴파일러에 특화된 모델은 이러한 사례를 " +"많이 확인하고 먼저 테스트할 가치가 있는 소스 코드 변형을 학습할 수 있습니다." + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"우리가 이미 동작을 이해하고 있는 최종 매칭 문제에서 기회는 특히 분명합니다. 그런 다음 이 컴파일러가 관찰된 명령으로 변환하는 일반적인" +" 소스 코드 배열을 묻습니다. 전문화는 모델이 이러한 형태를 보다 효율적으로 제안하는 데 도움이 될 수 있으며, 목표는 여전히 어떤 " +"가설이 살아남는지 결정합니다." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"유용한 패턴에는 적용 조건이 함께 남아야 한다. TH08은 TH095와 TH09보다 오래된 Visual C++ 버전을 사용한다. " +"TH04은 DOS 시대의 다른 컴파일러를 사용하며, {ph0}플레이어 코드 재구성{ph1}에는 소스 패턴과 실행 파일의 링크 방식에 관한" +" 다른 가설이 필요했다. 같은 저자라는 사실은 초기 가정을 제공하지만, 그것이 적용되는지는 각 대상에서 확인해야 한다. 이런 맥락을 " +"구별하는 것도 특화 모델이 배울 일이다." + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "이 경험은 어디에 저장되어야 합니까?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"모델 훈련을 통해 이러한 패턴을 가르치기로 결정하기 전에 우리가 이미 저장소에 보관하고 있는 지식을 살펴보겠습니다. {ph0}이전 " +"에세이{ph1}에서는 그것이 프로젝트의 작업 메모리가 되는 것에 대해 썼습니다. 그 메모리에는 컴파일러 교훈과 이를 유용하게 만든 소스 " +"및 실패한 실험이 포함됩니다." + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"에이전트는 해당 기록을 검색하여 알려진 결과로 시작하고 해당 기록에 어떻게 도달했는지 검사할 수 있습니다. 또한 동일한 맥락에서 이미 " +"실패한 대안을 피할 수도 있습니다. 모델의 훈련된 매개변수를 변경하지 않고도 시작점이 향상됩니다." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"TH09의 적 생성 함수를 재구성할 때, {ph0}GPT-6-Luna-max 세션{ph1}은 TH08의 관련 소스 코드에서 가설을 " +"얻었다. 이전 코드는 루프의 구성과 내부 실패 처리에 대한 단서를 제공했다. TH09 자체의 증거로 게임별 세부 사항을 채웠고, 소스에서" +" 새로 빌드해 함수 전체의 일치를 확인했다." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}\"모델이 컴파일러의 이상한 점을 몰랐습니다\"와 \"모델이 이를 사용할 수 없었습니다\"는 다른 문제입니다.{ph1} 검색을 " +"통해 첫 번째 문제를 해결할 수 있지만 해당 사실을 유용한 후보로 바꾸는 작업은 여전히 필요합니다. 그리고 후보 소스 코드가 실패하면 " +"모델은 다음 시도에서 결과가 무엇을 의미하는지 결정해야 합니다. 관련 패턴을 아는 것은 해당 프로세스의 시작일뿐입니다." + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"그러한 이유로 저는 어떤 비교에서도 검색 성능이 좋은 더 작은 범용 AI 모델을 포함하겠습니다. 동일한 경험 라이브러리를 제공하면 교육이" +" 추가하는 것이 무엇인지 식별하는 데 도움이 됩니다. 즉, 더 나은 후보 코드 생성, 피드백 후 더 나은 결정 또는 둘 다입니다." + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "다음 유용한 실험 학습" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"피드백 이후의 결정은 제가 가장 연구하고 싶은 것입니다. 에이전트 재구성에서 모델은 설명을 제안하고 이를 프로그램에 대해 테스트합니다. " +"후보 소스 코드가 실패하더라도 그 결과는 남은 가능성을 좁히고 보다 유용한 다음 실험을 제안할 수 있습니다." + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "" +"임시 결과 예제를 다시 고려해보세요. 최종 소스에는 제대로 작동한 배열이 표시되지만 해당 소스로의 경로에는 더 많은 정보가 포함되어 " +"있습니다. 다음 각 실험은 여전히 ​​변경해야 할 사항을 식별하는 데 도움이 되었습니다." + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "실험" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "그 결과가 우리에게 가르쳐준 것" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "결과를 복사하는 다른 방법을 시도해 보세요." + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "복사 코드는 변경되지만 기능은 여전히 다릅니다." + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "반환된 값을 직접 사용" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "복사는 원래 패턴을 따르지만 임시 저장소는 여전히 다릅니다." + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "모든 임시 변수를 동시에 유효한 상태로 유지" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "별도의 저장소를 갖지만 하나는 나중에 충돌 검사에 사용되는 값과 여전히 겹칩니다." + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "충돌 검사 값을 별도로 유지하십시오." + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "소스에서 완전히 재컴파일하면 완전한 일치가 확인됩니다." + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "위의 공격 함수 재구성에서 선택한 실험을 우리에게 가르친 내용을 기준으로 그룹화했습니다." + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"이 시퀀스를 유지하는 훈련 기록은 최종 소스보다 더 많은 것을 가르칠 수 있습니다. 이는 제안된 각 변경 사항을 관찰된 결과 및 다음 " +"결정에 연결합니다. 비효과적인 변형을 유지하는 것도 중요합니다. 이는 해당 맥락에서 어떤 가설이 이미 테스트되었는지 나중에 에이전트에게 " +"알려줍니다." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}모델이 피드백을 사용하는 방법을 배우기를 원합니다.{ph1} 중립적인 결과는 변화를 재고해야 하는 이유입니다. 변경된 불일치는 " +"다른 원인을 가리킬 수도 있습니다. 로컬 편집이 더 이상 정보를 제공하지 않으면 에이전트는 소스 표현을 다시 방문하거나 증거를 다시 " +"검사할 수 있어야 합니다." + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"그러한 선택을 하는 방법을 배우려면 자율성이 필요합니다. 때때로 유용한 다음 단계는 다른 편집 내용을 컴파일하는 대신 다른 호출자를 " +"검사하는 것입니다. 필수 재작성의 엄격한 순서는 모델이 학습하기를 원하는 동작의 일부와 함께 해당 선택을 제거합니다." + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "강화 학습에 리버스 엔지니어링이 흥미로운 이유" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"범위가 정해진 재구성은 이런 선택을 연구할 실용적인 환경을 제공한다. 대상과 컴파일러 버전을 고정하면 많은 소스 코드 실험에서 빠르고 " +"반복 가능한 피드백을 얻을 수 있다. 에이전트는 후보 코드를 컴파일하고 차이를 살펴본 뒤 다음 단계를 선택할 수 있다." + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"강화 학습은 이런 피드백을 통해 의사 결정 과정을 훈련할 수 있다. 정의된 검증을 통과한 후보는 구체적인 결과가 되고, 시도 기록은 그 " +"결과에 도달하는 데 얼마나 많은 작업이 필요했는지 보여 준다." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"이미 이 방향을 뒷받침하는 연구가 있다. {ph0}LLM4Decompile{ph1}은 디컴파일에 특화된 모델을 연구한다. " +"{ph2}AutoDecompiler{ph3}는 컴파일과 실행 피드백으로 여러 차례 개선하는 과정을 학습한다. 이 연구들은 기능 복원에 " +"초점을 맞춘다. 나는 이를 출발점으로 삼아, 당시 컴파일러의 출력과 일치하는 소스 코드를 찾는 관련 과제를 연구하고 싶다." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"그처럼 명확한 과제를 만들려면, 먼저 함수가 어떤 리소스를 책임지는지 확인하거나 실행 중인 프로그램의 동작을 관찰할 새로운 방법을 " +"설계해야 할 수 있다. TH08에서는 {ph0}충돌 판정의 차이를 추적하다가 원본 프로그램의 부동 소수점 계산 방식에 도달했다{ph1}." +" 에이전트는 유용한 수정을 검증하기 전에 무엇을 측정할지부터 알아내야 했다." + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "" +"이는 광범위하게 역량을 갖춘 모델의 또 다른 역할을 제시합니다. 즉, 우선 문제를 확인할 수 있도록 돕는 것입니다. 해당 검사가 존재하면" +" 학습된 검색 정책이 얼마나 멀리까지 도달할 수 있는지 조사할 수 있습니다." + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "검증체커가 잘못된 경우" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"검증 결과를 학습에 사용하면 그 검증의 범위도 학습 환경의 일부가 된다. 나는 이런 참조 기준이나 검증기를 oracle이라고 부른다. " +"반복 가능한 답이라도, 실제로 무엇을 확인한 답인지 이해해야 한다." + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"TH08은 해당 적용 범위 외부에 얼마나 많은 것을 숨길 수 있는지 보여주었습니다. 재구성된 일부 함수는 잘못된 부동 상수와의 정확한 " +"비교를 통과했습니다. 비교기는 명령을 확인하기 전에 재배치된 주소를 조정했지만 확인을 위해 명시적으로 기록된 경우에만 해당 주소 뒤에 " +"있는 값을 확인했습니다. 다른 리터럴 참조는 해당 값을 검사하지 않고 통과할 수 있습니다." + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"이러한 격차를 해소하기 위해 {ph0}광범위한 감사{ph1}를 통해 이미 검증을 통과한 함수에서 잘못된 상수가 발견되었습니다. 한 " +"계산에서는 재구성된 소스 코드에 {ph2}가 추가된 반면 원본 코드에는 {ph3}가 추가되었습니다." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}기존 검증으로 보상하면 모델이 잘못된 재구성을 학습할 수도 있다.{ph1} 이 검증기로 RL 모델을 훈련한 것은 아니다. 실제로" +" 관찰한 실패는 검증 자체의 오류였다. 하지만 이를 보상으로 사용했다면 같은 사각지대가 학습 환경에 들어갔을 것이다." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"기능 테스트에도 비슷한 사각지대가 있을 수 있습니다. {ph0}LLM 디컴파일러에서 차등 퍼징을 사용한 연구{ph1}에서는 제공된 테스트" +" 외부의 동작 차이를 발견했습니다. 그러므로 우리는 그것이 수행되는 사례의 관점에서 합격 테스트를 이해해야 합니다. 마찬가지로 명령어 " +"일치는 확인하는 바이트와 데이터 측면에서 이해되어야 합니다." + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"어느 검증이든 보상으로 사용하기 전에는 의도적으로 틀린 결과를 넣어 시험해 보고 싶다. 최종 승인 기준도 에이전트가 수정할 수 있는 소스" +" 코드 밖에 두어야 한다. 올바르게 재구성해 검증을 통과하도록 해야 하기 때문이다. 그렇지 않으면 대상에서 복사한 바이트 배열이 유용한 " +"소스 복원 없이 단순한 채점 기준을 통과할 수 있다." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "" +"{ph0}학습 모델의 개선과 검증기의 개선은 같은 연구 문제다.{ph1} 모델이 우리가 주는 피드백을 더 잘 최적화할수록, 그 피드백 " +"자체를 이해하는 일도 중요해진다." + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "실행할 가치가 있는 비교" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"이러한 점검을 마친 후 고정된 VC7.1 작업 계열에 대한 비교를 시작합니다. 첫째, 강력한 범용 AI 모델과 더 작은 모델에 대한 " +"기준선을 설정하겠습니다. 더 작은 모델에 저장소 지식을 추가하면 검색이 어떻게 변경되는지 확인할 수 있습니다. 거기에서 감독 전문화와 " +"RL 훈련 버전을 통해 훈련에 추가되는 것이 무엇인지 검토할 수 있습니다." + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"이러한 비교를 유익하게 만들기 위해 각 모델은 동일한 대상 증거와 도구를 받게 됩니다. 훈련별 비교를 위해 기본 모델과 사용 가능한 " +"지식도 고정된 상태로 유지합니다. 반복적인 시도는 우연히 성공한 후보 솔루션과 신뢰할 수 있는 검색 전략을 구별하는 데 도움이 됩니다." + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"그런 다음 두 가지 시작 조건을 분리합니다. 즉, 명령에서 함수를 재구성하는 것과 유지 관리되는 소스에서 마지막 몇 가지 차이점을 닫는 " +"것입니다. 특화 AI 모델은 두 번째 작업에 탁월할 수 있지만 범용 AI 모델은 두 번째 작업에 도달하는 데 필요한 많은 작업을 " +"수행합니다. 그것들을 개별적으로 측정하면 업무 분할이 드러날 것입니다." + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"두 과제 모두 학습 데이터와 검색 자료에서 제외한 테스트 사례가 필요하다. 관련 Touhou 게임은 엔진 코드를 공유하므로, 게임 하나만" +" 제외해도 거의 같은 함수가 학습 데이터에 남을 수 있다. 대신 관련 소스 코드 계열 전체를 따로 남겨 두고, 검증된 정답을 학습 " +"데이터와 검색 라이브러리 양쪽에서 제외하겠다." + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"측정할 결과는 완전하고 독립적으로 검증된 일치다. 후보 제안 수나 컴파일 횟수의 예산을 같게 하면 탐색 품질을 비교할 수 있다. 컴파일을" +" 포함한 총 시간과 비용은 그 품질이 효율적인 워크플로로 이어지는지 보여 준다. 학습 비용은 별도로 계산해야 한다." + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"두 측정 모두 중요합니다. 유용한 정보를 제공하지 않는 컴파일이 더 많이 발생하면 값싼 제안으로 인해 비용이 많이 드는 작업 흐름이 " +"발생할 수 있습니다. 반대로, 유용한 실험을 더 빨리 발견하면 느린 모델이 더 경제적일 수 있습니다. 비교에는 이러한 비용이 포함되어야 " +"합니다." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"승인된 결과를 계산하면 중간 진행 상황을 관점에서 볼 수 있습니다. 하나의 TH09 {ph0}재생 저장 후보{ph1}는 컴파일된 함수의 " +"크기가 예상과 같았기 때문에 유망해 보였지만 전체 비교에서는 여전히 상당한 차이가 발견되었습니다. 컴파일러가 명령을 배열하는 방식을 " +"변경하면 근본적인 문제를 해결하지 않고도 후보가 더 가까워 보이게 만들 수도 있습니다. 이러한 진단은 다음 실험의 지침이 될 수 있지만 " +"전체 승인 확인에 대해 \"가까워지는\" 것에 대한 보상을 검증하겠습니다." + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"나는 이러한 결과의 패턴에 관심이 있습니다. 전문화된 AI 모델이 친숙한 컴파일러 제품군 내에서 잘 작동한다면 툴체인 변경 후에도 해당 " +"장점이 유지됩니까? 두 AI 모델 모두 좋은 검색 결과를 얻은 후에도 훈련을 통해 얼마나 추가되나요? 답변은 각 모델 종류가 가장 유용한" +" 위치를 결정하는 데 도움이 됩니다." + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "어떤 에이전트가 필요할까?" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"모델이 여러 단계에서 도움이 되는 것으로 밝혀지면 특화 AI 모델에 액세스할 수 있는 광범위한 에이전트가 유용한 배열이 될 수 있습니다." +" 작업이 익숙한 컴파일러 검색이 되면 특화 AI 모델에 후보를 요청할 수 있습니다. 결과가 더 이상 이해되지 않는 경우 더 넓은 범위의 " +"에이전트는 대상 증거로 돌아가거나 측정 자체를 조사할 수 있습니다." + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "" +"이러한 배열에서 전문화는 조사가 진행됨에 따라 에이전트가 선택할 수 있는 도구가 됩니다. 에이전트는 이전의 돌파구를 가능하게 했던 방향을" +" 자유롭게 변경할 수 있습니다." + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"이는 이전 에세이에서 설명한 산업 변화에서 자연스럽게 나온 것입니다. 더 많은 실험을 실행할 수 있게 되면 작업 구성 방식이 변경됩니다." +" 또한 어떤 결정에 폭 넓은 판단이 필요한지, 어떤 결정은 특정 기술에 대한 반복적인 경험을 통해 개선되는지 질문할 이유를 제공합니다." + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"지금까지 가장 강한 범용 모델은 내가 해결하지 못했던 문제를 풀어내며 워크플로에서 자리를 얻었다. 그 성공 때문에 작업을 더 자세히 " +"살펴보고 싶다. 얼마나 많은 부분이 모델의 폭넓은 능력에 의존했을까? 이 종류의 재구성을 전문적으로 학습한 모델은 어디까지 담당할 수 " +"있을까?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "" +"{ph0}저장소는 질문을 테스트할 수 있는 방법을 제공합니다.{ph1} 해당 기록을 사용하여 비교를 구축하고 배운 내용을 확인하고 " +"싶습니다." + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "증거 및 모델 속성" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"예제에서는 연결된 커밋에 기록된 기능 수준 비교 기록을 설명합니다. 전체 게임 런타임 확인은 별도의 마일스톤입니다. 출처 및 일치 기록은" +" 2026년 10월 13일에 검토되었습니다." + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"TH09 라벨 {ph0}은 GPT-6-Astra을 의미합니다. {ph1}과(와) 관련된 모델은 시간이 지남에 따라 변경되었으므로 " +"라벨만으로는 특정 실행에 사용된 모델을 식별할 수 없습니다. 다른 인용 커밋의 명시적인 모델 이름은 기록된 속성을 제공합니다. 이러한 " +"기록에는 모든 실행에 대한 일관된 비용 또는 노력 측정이 포함되지 않습니다." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "" +"{ph0}TH09 임시 객체 수명:{ph1} {ph2}이전 컨텍스트 검토{ph3} 및 {ph4}소스에서 깔끔한 재컴파일을 통해 확인된 " +"완전한 재구성{ph5}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"{ph0}TH09 Front 콜백:{ph1} {ph2}일치하지 않는 진단 영역{ph3}, {ph4}Astra의 새로운 제어 흐름 " +"그래프{ph5} 및 {ph6}승인된 재컴파일 확인{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}컴파일러 지식:{ph1} {ph2}TH095 식별자 버킷 동작 재사용{ph3}, {ph4}TH04 플레이어 소스 코드 및 링커 " +"순서{ph5} 및 {ph6}Luna의 TH09 적 생성 기능에 대한 완전한 재구성{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}검사 및 진단:{ph1} {ph2}TH08 부동 소수점 상수 감사{ph3}, {ph4}TH08 수치 조사{ph5} 및 " +"{ph6}TH09 재생 저장 재구성{ph7}." + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "" +"제안한 특화 모델과 RL의 비교는 앞으로 해 볼 실험이다. 프로젝트 이력이 그 동기를 제공하지만, 이 글에서 학습된 특화 모델을 평가한 " +"것은 아니다." + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "리버스 엔지니어링에 더 큰 모델이 필요할까? | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "" +"Touhou 재구성을 통해 일반 모델, 전문 모델 및 컴파일러 피드백을 통해 더 나은 가설을 제안하는 방법에 대해 배운 내용." + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "이 페이지에" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "모델 및 리버스 엔지니어링 에세이" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "선정된 재구성 실험" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "맨 위로" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "{ph0}상세 증거 기록{ph1}에는 비교 결과와 실험 맥락이 담겨 있다." + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "작성: N0zoM1z0 · 2026년 10월 13일 · 검토용 초안" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "설정 가이드" diff --git a/website/locales/messages.pot b/website/locales/messages.pot index ab1a4a17e..4d41b3f46 100644 --- a/website/locales/messages.pot +++ b/website/locales/messages.pot @@ -12,6 +12,7 @@ msgid "Skip to content" msgstr "" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 website/public/faq/index.html:113 #: website/public/first-investigation/index.html:113 @@ -29,6 +30,7 @@ msgid "Get started" msgstr "" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 website/public/faq/index.html:114 #: website/public/first-investigation/index.html:114 @@ -46,6 +48,7 @@ msgid "Showcases" msgstr "" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 website/public/faq/index.html:115 #: website/public/first-investigation/index.html:115 @@ -63,6 +66,7 @@ msgid "Blog" msgstr "" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 website/public/faq/index.html:116 #: website/public/first-investigation/index.html:116 @@ -101,32 +105,57 @@ msgstr "" #: website/public/blog/index.html:200 #, python-brace-format msgctxt "page:blog/index.html" -msgid "Game reconstruction{ph0}Essay" +msgid "Model specialization{ph0}Essay" msgstr "" #: website/public/blog/index.html:202 msgctxt "page:blog/index.html" -msgid "The industrial revolution in reverse engineering" +msgid "Does reverse engineering need a bigger model?" msgstr "" #: website/public/blog/index.html:203 msgctxt "page:blog/index.html" msgid "" +"What Touhou reconstruction suggests about general models, specialist models and " +"learning from compiler feedback." +msgstr "" + +#: website/public/blog/index.html:207 website/public/blog/index.html:222 +msgctxt "page:blog/index.html" +msgid "Read the article" +msgstr "" + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "" + +#. {ph0}:
+#: website/public/blog/index.html:214 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Game reconstruction{ph0}Essay" +msgstr "" + +#: website/public/blog/index.html:216 +msgctxt "page:blog/index.html" +msgid "The industrial revolution in reverse engineering" +msgstr "" + +#: website/public/blog/index.html:217 +msgctxt "page:blog/index.html" +msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about agents, " "verification and knowledge that compounds across projects." msgstr "" -#: website/public/blog/index.html:208 -msgctxt "page:blog/index.html" -msgid "Read the article" -msgstr "" - -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 website/public/faq/index.html:565 #: website/public/first-investigation/index.html:515 @@ -143,7 +172,8 @@ msgctxt "shared" msgid "Source" msgstr "" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 website/public/faq/index.html:566 #: website/public/first-investigation/index.html:516 @@ -160,7 +190,8 @@ msgctxt "shared" msgid "MIT license" msgstr "" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 website/public/faq/index.html:567 #: website/public/first-investigation/index.html:517 @@ -177,7 +208,8 @@ msgctxt "shared" msgid "Join the community" msgstr "" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 website/public/faq/index.html:568 #: website/public/first-investigation/index.html:518 @@ -196,7 +228,8 @@ msgstr "" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 website/public/faq/index.html:573 #: website/public/first-investigation/index.html:523 @@ -227,6 +260,8 @@ msgid "" msgstr "" #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -253,6 +288,7 @@ msgid "REA — Find out how software works. Reverse engineering with your coding msgstr "" #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 website/public/faq/index.html:108 #: website/public/first-investigation/index.html:108 @@ -270,6 +306,7 @@ msgid "REA home" msgstr "" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 website/public/faq/index.html:112 #: website/public/first-investigation/index.html:112 @@ -287,6 +324,7 @@ msgid "Main navigation" msgstr "" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 website/public/faq/index.html:130 #: website/public/first-investigation/index.html:130 @@ -304,6 +342,7 @@ msgid "REA on GitHub" msgstr "" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 website/public/faq/index.html:150 #: website/public/first-investigation/index.html:150 @@ -321,6 +360,7 @@ msgid "Join REA on Discord" msgstr "" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 website/public/faq/index.html:169 #: website/public/first-investigation/index.html:169 @@ -337,11 +377,1005 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "" +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later sessions " +"have solved problems that earlier work left unresolved." +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to learn.{ph1} Some " +"exact matches depend on narrow, reusable source patterns." +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with good " +"retrieval may already know enough to make progress." +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value of feedback" +" depends on what the checker actually verifies." +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the result I " +"want from the whole agent." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an agent can " +"carry out with access to a program and a way to check its work. Most of my experience " +"comes from reconstructing games, especially Touhou. As I have changed models, the " +"repositories have kept a record of what each session managed to recover." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained source under" +" a pinned historical toolchain and check whether it reproduces the target function. " +"When a later model succeeds where earlier work stalled, the source changes show what " +"made that progress possible." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but the " +"compiler still stored temporary results differently from the original. The remaining " +"problem was how long those results needed to stay alive and when their storage could " +"be reused." +msgstr "" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing several ordinary" +" source arrangements. When {ph2}GPT-6.1-Sol returned to the problem{ph3}, it found a " +"useful hypothesis about how long those temporary values needed to stay alive." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation positions. In " +"C++, a temporary result stays alive until the expression using it finishes. Grouping " +"the real operations into one expression kept those results alive together, so the " +"compiler could no longer reuse the same storage for all of them." +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision checks. Giving " +"that value its own lifetime resolved the remaining overlap. After several targeted " +"experiments, {ph0}a clean rebuild confirmed that the full function matched{ph1}." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The lifetime " +"hypothesis gave the agent a new direction; compiler feedback helped it refine that " +"hypothesis into a source arrangement that matched." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the obstacle was" +" how several branches shared their final work. {ph0}GPT-6.1-Sol's earlier work{ph1} " +"got parts of the function to match, but the branches still joined up differently from " +"the original." +msgstr "" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main paths now " +"led to a shared final update and return. In that source structure, the compiler " +"combined the branches in the same way as the original. The complete function matched, " +"and a {ph2}separate rebuild check confirmed it{ph3}." +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1} Both " +"cases give me a reason to take general model capability seriously: an agent can keep " +"trying local variations for a long time before finding a better way to express the " +"surrounding work." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and recorded " +"failures. That accumulated work was part of their advantage. The history lets us " +"inspect the discoveries and their checks; a controlled comparison would help separate " +"the effect of the model from the experience it inherited." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress came from " +"finding a new representation, while much of the remaining work involved testing source" +" forms against a familiar compiler. How much needs broad reasoning ability, and how " +"much could a model learn through repeated experience with that compiler and code?" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of the game " +"code comes from the same author, ZUN, so recurring habits are a reasonable starting " +"assumption. The repositories back that up with useful examples: related loops and " +"helper arrangements have supplied hypotheses across games." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. Under a " +"particular version and set of options, small changes in source can produce repeatable " +"differences in machine code. Some of those differences are surprisingly obscure." +msgstr "" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could change where" +" VC7.1 stored it{ph1}. Moving the declaration alone did not solve the layout, but an " +"earlier background function had revealed a naming pattern that affected the compiler's" +" choice. That gave us a more promising hypothesis for {ph2}the reconstruction of " +"{ph3}{ph4}." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout without " +"adding storage. The full function then matched." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it arrives. A " +"specialist trained on this compiler could encounter many such cases and learn which " +"source variations are worth testing first." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we already " +"understand the behavior. We are then asking which ordinary source form this compiler " +"turns into the observed instructions. Specialization could help the model propose " +"those forms more efficiently, while the target still determines which hypotheses " +"survive." +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an earlier " +"Visual C++ version than TH095 and TH09. TH04 uses a different DOS-era compiler, and " +"its {ph0}player reconstruction{ph1} needed different hypotheses about source patterns " +"and how the compiled code was combined into an executable. Shared authorship gives us " +"a prior, but each target tells us whether it applies. Distinguishing those contexts is" +" part of what a specialist would need to learn." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look at the " +"knowledge we already keep in the repository. In the {ph0}previous essay{ph1}, I wrote " +"about it becoming the project's working memory. That memory includes compiler lessons," +" along with the source and failed experiments that made them useful." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and inspect how we " +"reached it. It can also avoid alternatives that have already failed in the same " +"context. The starting point improves without changing the model's weights." +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max session{ph1} " +"drew a hypothesis from TH08's corresponding source family. That earlier source " +"suggested how to structure the loop and handle failures within it. TH09's own evidence" +" supplied the game-specific details, and clean rebuilds confirmed the complete match." +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could not use it\"" +" are different problems.{ph1} Retrieval may solve the first, but turning that fact " +"into a useful candidate still takes work. And if the candidate fails, the model must " +"decide what the result means for its next attempt. Knowing the relevant pattern is " +"only the beginning of that process." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval in any " +"comparison. Giving it the same library of experience would help us identify what " +"training adds: better candidate generation, better decisions after feedback, or both." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In agentic " +"reconstruction, the model proposes an explanation and tests it against the program. " +"Even when the candidate fails, the result can narrow the remaining possibilities and " +"suggest a more useful next experiment." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the arrangement " +"that worked, but the route to that source contains more information. Each of the " +"following experiments helped identify what still needed to change." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Copying follows the original pattern, but temporary storage still differs." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for collision " +"checks." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped by what " +"they taught us." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final source alone." +" It connects each proposed change to an observed result and the next decision. Keeping" +" ineffective variations matters too: they tell a later agent which hypotheses have " +"already been tested in that context." +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral result is a " +"reason to reconsider the variation; a changed mismatch may point to another cause. " +"When local edits stop being informative, the agent should be able to revisit the " +"source representation or inspect the evidence again." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next step is " +"inspecting another caller rather than compiling another edit. A rigid sequence of " +"required rewrites would remove that choice, along with part of the behavior we want " +"the model to learn." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these choices. " +"Once the target and compiler are pinned, many source experiments produce quick, " +"repeatable feedback. The agent can compile a candidate, inspect the mismatch and use " +"that observation to choose its next step." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the feedback " +"it receives. A candidate accepted by a defined check gives us a concrete outcome, " +"while the sequence of attempts lets us observe how much work it took to reach it." +msgstr "" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1} studies " +"models specialized for decompilation. {ph2}AutoDecompiler{ph3} trains multi-turn " +"refinement using compiler and execution feedback. Their studies focus on functional " +"recovery. For this work, I would use them as a starting point for the related task of " +"finding source that matches a historical compiler's output." +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish what a " +"function owns or devise a new runtime measurement. In TH08, for example, a " +"{ph0}collision difference led back to how the original program handled floating-point " +"calculations{ph1}. Before the agent could test a useful correction, it had to work out" +" what to measure." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the problem " +"checkable in the first place. Once that check exists, we can investigate how far a " +"learned search policy can get with it." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the model learns. " +"I call the reference or checker an oracle. Even if it gives a repeatable answer, we " +"still need to understand what that answer covers." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed functions " +"passed their exact comparisons with wrong floating constants. The comparator adjusted " +"relocated addresses before checking instructions, but it checked the values behind " +"those addresses only when they had been explicitly recorded for verification. Other " +"literal references could pass without their values being examined." +msgstr "" + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in functions that" +" had already been accepted. In one calculation, the reconstructed source added {ph2} " +"where the original added {ph3}." +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the observed " +"failure was in the check itself. But using that check as a reward would have made the " +"same blind spot part of the learning environment." +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing research on" +" LLM decompilers{ph1} has found behavior differences beyond the supplied tests. " +"Passing those tests therefore needs to be read in terms of the cases they exercise, " +"just as an instruction match needs to be read in terms of the bytes and data it " +"checks." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with deliberate " +"failures. I would also keep final acceptance outside the candidate's editable source, " +"so the model has to satisfy the check through its reconstruction. Otherwise, something" +" like a byte array copied from the target could satisfy a naive score without " +"recovering useful source." +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same research " +"problem.{ph1} As the learner gets better at optimizing the feedback we give it, " +"understanding that feedback becomes more important too." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 task family." +" First, I would establish baselines for a strong general model and a smaller one. " +"Adding repository knowledge to the smaller model would show what retrieval changes. " +"From there, supervised specialization and an RL-trained version would let us examine " +"what training adds." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same target " +"evidence and tools. For the training-specific comparisons, I would keep the base model" +" and available knowledge fixed as well. Repeated trials would help distinguish a " +"reliable search strategy from a lucky candidate." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function from its " +"instructions, and closing the last few differences in maintained source. A specialist " +"might be excellent at the second task while a general model does much of the work " +"needed to reach it. Measuring them separately would reveal that division of work." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games share engine" +" code, holding out a game's name would still allow nearly identical functions to " +"appear in training. I would instead hold out source families and keep their accepted " +"answers out of both training and retrieval." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated matches. " +"Giving each model the same candidate or compile budget would help compare search " +"quality. Measuring elapsed time and total cost, including compilation, would tell us " +"whether that quality produces an efficient workflow. Training costs would need their " +"own accounting too." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive workflow if it " +"causes more uninformative compiles. Conversely, a slower model may pay for itself by " +"finding a useful experiment sooner. The comparison should capture those costs." +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. One TH09 " +"{ph0}replay-save candidate{ph1} looked promising because the compiled function had the" +" expected size, but a full comparison still found substantial differences. Changes in " +"how the compiler arranges instructions can also make a candidate look closer without " +"resolving the underlying problem. Such diagnostics can guide the next experiment, but " +"I would validate any reward for \"getting closer\" against the full acceptance check." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist does well " +"within a familiar compiler family, does that advantage survive a toolchain change? And" +" once both models have good retrieval, how much does training still add? The answers " +"would help us decide where each kind of model is most useful." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement might be a " +"broad agent with access to a specialist. Once a task becomes a familiar compiler " +"search, it could ask the specialist for candidates. If the results stop making sense, " +"the broader agent could return to the target evidence or investigate the measurement " +"itself." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as the " +"investigation develops. The agent keeps the freedom to change direction that made the " +"earlier breakthroughs possible." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous essay. " +"Being able to run many more experiments changes how we organize the work. It also " +"gives us a reason to ask which decisions need broad judgment and which improve through" +" repeated experience with a particular craft." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by opening " +"problems I had left unresolved. Those successes are what make me want to examine the " +"work more closely: how much depended on the model's breadth, and how much could be " +"handled by a model trained in this particular kind of reconstruction?" +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like to use " +"that record to build the comparison and see what we learn." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and experiment " +"context." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the linked " +"commits. Whole-game runtime checks are separate milestones. Source and matching " +"records were reviewed on 13 October 2026." +msgstr "" + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model used at the " +"time, so that label alone does not identify an individual run. Explicit model names in" +" the other cited commits establish their recorded attribution; the histories do not " +"contain uniform per-run cost or effort measurements." +msgstr "" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and " +"{ph4}complete cold reconstruction{ph5}." +msgstr "" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, {ph4}Astra's " +"new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, {ph4}TH04 " +"player source and linker order{ph5} and {ph6}Luna's TH09 enemy-spawn closure{ph7}." +msgstr "" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, {ph4}TH08 " +"numerical investigation{ph5} and {ph6}TH09 replay-save reconstruction{ph7}." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The project " +"histories motivate them; no trained specialist was evaluated for this essay." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models and " +"learning to propose better hypotheses from compiler feedback." +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "" + #: website/public/blog/touhou-reconstruction/index.html:103 msgctxt "page:blog/touhou-reconstruction/index.html" msgid "Skip to content" diff --git a/website/locales/pl/messages.po b/website/locales/pl/messages.po index 3a6657178..d97cd87f1 100644 --- a/website/locales/pl/messages.po +++ b/website/locales/pl/messages.po @@ -32,18 +32,18 @@ msgid "Thoughts on reverse engineering." msgstr "Myśli o inżynierii odwrotnej." #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "Rekonstrukcja gry{ph0}Esej" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "Rewolucja przemysłowa w inżynierii odwrotnej" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " @@ -52,19 +52,20 @@ msgstr "" "Co Instrukcja RE i rekonstrukcji TH08, TH095 i TH04 nauczył mnie O agentów, " "weryfikacja i wiedza, że związki całej projektów." -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "Przeczytaj artykuł" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "Przez N0zoM1z0 * 10 października 2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -100,6 +101,8 @@ msgstr "" "doświadczenia z agentami REA i AI." #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -136,6 +139,7 @@ msgstr "" "agentem kodującym." #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -156,6 +160,7 @@ msgid "REA home" msgstr "Strona główna REA" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -176,6 +181,7 @@ msgid "Main navigation" msgstr "Główna nawigacja" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -196,6 +202,7 @@ msgid "REA on GitHub" msgstr "REA na GitHub" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -216,6 +223,7 @@ msgid "Join REA on Discord" msgstr "Dołącz do REA na Discordzie" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -235,7 +243,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "Obserwuj REA na X" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "Do góry" @@ -11618,6 +11626,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "Ten sam odstęp: 256 ÷ 16 = 16 jednostek kąta = 22,5°" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -11638,6 +11647,7 @@ msgid "Showcases" msgstr "Przykłady" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -11658,6 +11668,7 @@ msgid "Blog" msgstr "Blog" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -11678,6 +11689,7 @@ msgid "Get started" msgstr "Pierwsze kroki" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -11697,7 +11709,8 @@ msgctxt "shared" msgid "Guides" msgstr "Poradniki" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -11717,7 +11730,8 @@ msgctxt "shared" msgid "Source" msgstr "Kod źródłowy" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -11737,7 +11751,8 @@ msgctxt "shared" msgid "MIT license" msgstr "Licencja MIT" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -11757,7 +11772,8 @@ msgctxt "shared" msgid "Join the community" msgstr "Dołącz do społeczności" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -12723,6 +12739,1384 @@ msgstr "" "1.2, aby uzyskać Evidence z zapisu w REA offline, lub połącz serwer MCP " "Everywhere, aby analizować zapisany ruch z agentem." +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "Modele specjalistyczne{ph0}Esej" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "Czy inżynieria odwrotna potrzebuje większego modelu?" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "" +"Co rekonstrukcja Touhou mówi o modelach ogólnych, modelach specjalistycznych" +" i uczeniu się na podstawie informacji zwrotnych z kompilatora." + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Przez N0zoM1z0 · 13 października 2026 r" + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "Przejdź do treści" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "" +"{ph0}Strona główna{ph1} / {ph2}Blog{ph3} / Modele i inżynieria odwrotna" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "Esej" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "Czy inżynieria odwrotna potrzebuje większego modelu?" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Przez N0zoM1z0 · 13 października 2026 r" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "Najważniejsze" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "" +"{ph0}Możliwości modelu wpływają na to, jakie hipotezy może postawić agent " +"AI.{ph1} Późniejsze sesje rozwiązały problemy, które nie zostały rozwiązane " +"wcześniej." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "" +"{ph0}Znany kompilator oferuje konkretne wzorce do nauki dla " +"wyspecjalizowanego modelu.{ph1} Niektóre dokładne dopasowania kodu " +"maszynowego zależą od konkretnych wzorców kodu źródłowego, które można " +"ponownie wykorzystać." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "" +"{ph0}W rzetelnym porównaniu uwzględnij wiedzę o repozytorium.{ph1} Mniejszy " +"model z dobrym wyszukiwaniem wiedzy może już mieć wystarczającą ilość " +"informacji, aby poczynić postępy." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "" +"{ph0}Wytrenuj model, aby wybrał kolejny przydatny eksperyment i przetestuj " +"jego moduł weryfikujący.{ph1} Opinia jest użyteczna tylko w takim stopniu, w" +" jakim moduł sprawdzający weryfikuje właściwe rzeczy." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "" +"{ph0}Oceń zweryfikowane wyniki rekonstrukcji pod względem czasu i " +"kosztów.{ph1} Właśnie to chcę zmierzyć w przypadku pełnego przepływu pracy " +"agenta AI." + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "W tym artykule" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}Co zmieniły silniejsze modele{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}Dlaczego się specjalizować?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}Gdzie należy przechowywać to doświadczenie?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}Nauka kolejnego przydatnego eksperymentu{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}Inżynieria odwrotna i uczenie się przez wzmacnianie{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}Gdy osoba sprawdzająca myli się{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}Porównanie warte przeprowadzenia{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}Jakiego rodzaju agenta AI to sugeruje?{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "Co zmieniły silniejsze modele" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"Od sierpnia 2026 roku badam, ile inżynierii wstecznej może dokonać agent " +"mając dostęp do programu i możliwość sprawdzenia jego działania. Większość " +"mojego doświadczenia pochodzi z rekonstrukcji gier, szczególnie Touhou. " +"Ponieważ zmieniałem modele, repozytoria prowadziły rejestr tego, co udało " +"się odzyskać w każdej sesji." + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"Duża część tych prac ma na celu dokładną rekonstrukcję: kompilujemy " +"utrzymywane źródło w ramach historycznego zestawu narzędzi ze stałymi " +"wersjami i sprawdzamy, czy odtwarza ono funkcję docelową. Kiedy późniejszy " +"model odniesie sukces tam, gdzie wcześniejsze prace utknęły w martwym " +"punkcie, zmiany źródłowe pokazują, co umożliwiło ten postęp." + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "Zmienne tymczasowe wymagały nakładających się okresów istnienia" + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"Duża część logiki funkcji ataku TH09 została już zrekonstruowana, ale " +"kompilator nadal przechowywał tymczasowe wyniki inaczej niż oryginał. " +"Pozostałym problemem było to, jak długo wyniki były potrzebne do zachowania " +"żywotności i kiedy można było ponownie wykorzystać ich pamięć." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"{ph0}GPT-6-Sol rekord sesji{ph1} zgłosił tę niezgodność po przetestowaniu " +"kilku zwykłych ustaleń kodu źródłowego. Kiedy {ph2}GPT-6.1-Sol ponownie " +"zbadał problem{ph3}, zaproponował użyteczną hipotezę dotyczącą czasu życia " +"tych zmiennych tymczasowych." + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"Funkcja wygenerowała tymczasowe wyniki i skopiowała je do pozycji animacji. " +"W C++ tymczasowy wynik pozostaje aktywny aż do zakończenia wyrażenia, które " +"go używa. Grupowanie rzeczywistych operacji w jedno wyrażenie utrzymywało te" +" wyniki razem, więc kompilator nie mógł już ponownie używać tej samej " +"pamięci dla nich wszystkich." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"Jeden wynik nadal współdzielił pamięć o wartości używanej później do " +"sprawdzania kolizji. Nadanie tej wartości własnego czasu życia rozwiązało " +"pozostałe nakładanie się. Po kilku ukierunkowanych eksperymentach " +"{ph0}czysta rekompilacja ze źródła potwierdziła, że ​​pełna funkcja jest " +"zgodna{ph1}." + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"Ciekawi mnie, jak odkrycie i testy wzajemnie się wspierały. Hipoteza " +"dotycząca czasu życia obiektów tymczasowych nadała agentowi AI nowy " +"kierunek. Informacje zwrotne od kompilatora pomogły mu udoskonalić tę " +"hipotezę w celu uzyskania pasującego układu kodu źródłowego." + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "Inny wykres przepływu sterowania" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"Druga funkcja TH09 pokazuje, dlaczego ten nowy kierunek może mieć znaczenie." +" Tutaj przeszkodą był sposób, w jaki kilka oddziałów podzieliło się swoją " +"końcową pracą. We wcześniejszej pracy {ph0}GPT-6.1-Sol{ph1} części funkcji " +"pasowały, ale gałęzie nadal łączyły się inaczej niż w oryginale." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}GPT-6-Astra zmienił otaczający wykres przepływu sterowania{ph1}. Główne" +" ścieżki prowadziły teraz do wspólnej ostatecznej aktualizacji i powrotu. W " +"tej strukturze źródłowej kompilator połączył gałęzie w taki sam sposób jak " +"oryginał. Pełna funkcja została zgodna i {ph2}potwierdziła to osobna " +"kontrola odbudowy{ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}Zmiana reprezentacji otworzyła bardziej produktywną przestrzeń " +"poszukiwań.{ph1} Obydwa przypadki dają mi powód, aby poważnie traktować " +"możliwości modelu ogólnego: agent może przez długi czas testować lokalne " +"odmiany, zanim znajdzie lepszy sposób na wyrażenie otaczającej pracy." + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"Jednocześnie późniejsze sesje rozpoczynały się od wcześniejszych źródeł i " +"odnotowanych awarii. Ta skumulowana praca była częścią ich przewagi. " +"Historia pozwala nam na wgląd w odkrycia i ich sprawdzenie; kontrolowane " +"porównanie pomogłoby oddzielić wpływ modelu od odziedziczonego przez niego " +"doświadczenia." + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"Właśnie dlatego to pytanie jest dla mnie interesujące. Pewien postęp " +"nastąpił po znalezieniu nowej reprezentacji. Większość pozostałej pracy " +"polegała na testowaniu różnych rozwiązań kodu źródłowego w porównaniu ze " +"znanym kompilatorem. Ile z tego wymaga szerokiej zdolności rozumowania? Ile " +"model może się nauczyć, wielokrotnie pracując z tym kompilatorem i kodem?" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "" +"Dlaczego wyspecjalizowany model sztucznej inteligencji może się sprawdzić?" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"Touhou daje nam konkretny powód, aby oczekiwać, że to doświadczenie pomoże. " +"Duża część kodu gry pochodzi od tego samego autora, ZUN, więc powtarzające " +"się nawyki są rozsądnym założeniem wyjściowym. Repozytoria potwierdzają to " +"przydatnymi przykładami: powiązane pętle i układy pomocnicze dostarczyły " +"hipotez w różnych grach." + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "" +"Te wzorce źródłowe stają się bardziej szczegółowe, gdy dołączymy kompilator." +" W przypadku określonej wersji i zestawu opcji niewielkie zmiany w źródle " +"mogą powodować powtarzalne różnice w kodzie maszynowym. Niektóre z tych " +"różnic są zaskakująco niejasne." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"Na przykład w TH095 {ph0}nawet nazwa zmiennej lokalnej może mieć wpływ na " +"miejsce przechowywania jej przez VC7.1{ph1}. Przeniesienie deklaracji nie " +"rozwiązało układu przechowywania. Jednak wcześniejsza funkcja tła ujawniła " +"wzorzec nazewnictwa, który wpłynął na wybór kompilatora. Sugerowało to " +"bardziej obiecującą hipotezę dotyczącą {ph2}rekonstrukcji {ph3}{ph4}." + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "" +"Ponowne użycie tego wzorca dla zmiennej rozmiaru pliku pozwoliło uzyskać " +"wymagany układ bez dodawania pamięci. Pełna funkcja została wówczas " +"dopasowana." + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "" +"Jest to bardzo specyficzny szczegół, o którym model sztucznej inteligencji " +"ogólnego przeznaczenia może nie wiedzieć, kiedy po raz pierwszy napotka " +"problem. Model wyspecjalizowany dla tego kompilatora mógłby zobaczyć wiele " +"takich przypadków i dowiedzieć się, które odmiany kodu źródłowego warto " +"przetestować w pierwszej kolejności." + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"Możliwość jest szczególnie wyraźna w przypadku końcowych problemów z " +"dopasowywaniem, w których już rozumiemy zachowanie. Następnie pytamy, jaki " +"zwykły układ kodu źródłowego ten kompilator przekształca w obserwowane " +"instrukcje. Specjalizacja może pomóc modelowi w skuteczniejszym proponowaniu" +" tych form, podczas gdy cel nadal określa, które hipotezy przetrwają." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"Przydatne wzorce muszą zachować swój kontekst. TH08 używa wcześniejszej " +"wersji Visual C++ niż TH095 i TH09. TH04 używa innego kompilatora z ery " +"DOS-u. Do jego {ph0}rekonstrukcji kodu gracza{ph1} potrzebne były różne " +"hipotezy dotyczące wzorców kodu źródłowego i sposobu łączenia skompilowanego" +" kodu z plikiem wykonywalnym. Posiadanie tego samego autora daje nam wstępne" +" oczekiwania, ale każdy cel mówi nam, czy ma to zastosowanie. Aby rozróżnić " +"te konteksty, potrzebny byłby wyspecjalizowany model." + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "Gdzie należy przechowywać to doświadczenie?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"Zanim zdecydowałbym się uczyć tych wzorców poprzez szkolenie modelowe, " +"sprawdziłbym wiedzę, którą już przechowujemy w repozytorium. W " +"{ph0}poprzednim eseju{ph1} pisałem, że stanie się ona pamięcią roboczą " +"projektu. Pamięć ta obejmuje lekcje kompilatora wraz ze źródłem i nieudanymi" +" eksperymentami, które uczyniły je użytecznymi." + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"Pobierając ten rekord, agent może zacząć od znanego wyniku i sprawdzić, w " +"jaki sposób do niego dotarliśmy. Można również uniknąć alternatyw, które już" +" zawiodły w tym samym kontekście. Punkt początkowy poprawia się bez zmiany " +"przeszkolonych parametrów modelu." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"Podczas rekonstrukcji funkcji TH09 służącej do tworzenia wrogów, podczas " +"{ph0}GPT-6-Luna-max sesji{ph1} przyjęto hipotezę z powiązanego kodu " +"źródłowego TH08. Ten wcześniejszy kod sugerował, jak zorganizować pętlę i " +"poradzić sobie z błędami w niej występującymi. Zeznania TH09 dostarczyły " +"szczegółów specyficznych dla gry. Przebudowa ze źródła potwierdziła, że " +"​​cała funkcja jest zgodna." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}„Model nie wiedział, że dziwactwo kompilatora” i „model nie mógł go " +"użyć” to różne problemy.{ph1} Pobranie może rozwiązać pierwszy, ale " +"przekształcenie tego faktu w użyteczną kandydaturę nadal wymaga pracy. A " +"jeśli potencjalny kod źródłowy zawiedzie, model musi zdecydować, co oznacza " +"wynik przy następnej próbie. Znajomość odpowiedniego wzorca to dopiero " +"początek tego procesu." + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"Z tego powodu do każdego porównania uwzględniłbym mniejszy model sztucznej " +"inteligencji ogólnego przeznaczenia z dobrym wyszukiwaniem. Zapewnienie tej " +"samej biblioteki doświadczeń pomogłoby nam określić, co wnosi szkolenie: " +"lepsze generowanie kandydatów, lepsze decyzje po otrzymaniu informacji " +"zwrotnej lub jedno i drugie." + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "Nauka kolejnego przydatnego eksperymentu" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"Najbardziej chciałbym się uczyć tych decyzji po otrzymaniu informacji " +"zwrotnej. W rekonstrukcji agentowej model proponuje wyjaśnienie i testuje je" +" w porównaniu z programem. Nawet jeśli potencjalny kod źródłowy zawiedzie, " +"wynik może zawęzić pozostałe możliwości i zasugerować bardziej przydatny " +"następny eksperyment." + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "" +"Rozważmy ponownie przykład wyników tymczasowych. Ostateczne źródło pokazuje " +"układ, który zadziałał, ale trasa do tego źródła zawiera więcej informacji. " +"Każdy z poniższych eksperymentów pomógł określić, co należy jeszcze zmienić." + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "Eksperyment" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "Czego nauczył nas jego wynik" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "Wypróbuj inny sposób kopiowania wyników" + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "Kod kopiowania zmienia się, ale funkcja nadal jest inna." + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "Użyj bezpośrednio zwróconych wartości" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "" +"Kopiowanie odbywa się według oryginalnego wzorca, ale przechowywanie " +"tymczasowe nadal się różni." + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "Zachowaj ważność wszystkich zmiennych tymczasowych w tym samym czasie" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "" +"Dostają oddzielną pamięć, ale jedna z nich nadal pokrywa się z wartością " +"używaną później do sprawdzania kolizji." + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "Zachowaj wartość kontroli kolizji oddzielnie" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "Czysta rekompilacja ze źródła potwierdza pełne dopasowanie." + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "" +"Wybrane eksperymenty z powyższej rekonstrukcji funkcji ataku, pogrupowane " +"według tego, czego nas nauczyły." + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"Zapis szkoleniowy zachowujący tę sekwencję może nauczyć więcej niż samo " +"ostateczne źródło. Łączy każdą proponowaną zmianę z zaobserwowanym " +"rezultatem i następną decyzją. Utrzymywanie nieefektywnych odmian również ma" +" znaczenie: informują późniejszego agenta, które hipotezy zostały już " +"przetestowane w tym kontekście." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}Chciałbym, żeby model nauczył się korzystać ze informacji " +"zwrotnej.{ph1} Neutralny wynik jest powodem do ponownego rozważenia odmiany;" +" zmieniona niezgodność może wskazywać na inną przyczynę. Kiedy lokalne " +"zmiany przestaną mieć charakter informacyjny, agent powinien mieć możliwość " +"ponownego przejrzenia reprezentacji źródłowej lub ponownego sprawdzenia " +"dowodów." + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"Nauka dokonywania takich wyborów wymaga autonomii. Czasami przydatnym " +"następnym krokiem jest sprawdzenie innego obiektu wywołującego, zamiast " +"kompilowania kolejnej edycji. Sztywna sekwencja wymaganych przeróbek usunie " +"ten wybór wraz z częścią zachowań, których ma się nauczyć model." + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "" +"Dlaczego inżynieria odwrotna jest interesująca w uczeniu się przez " +"wzmacnianie" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"Rekonstrukcja o ustalonym zakresie daje praktyczne środowisko do badania " +"tych decyzji. Po ustaleniu wersji celu i kompilatora wiele eksperymentów z " +"kodem źródłowym zapewnia szybką, powtarzalną informację zwrotną. Agent może " +"skompilować kandydata, sprawdzić różnice i wybrać następny krok." + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"Uczenie się przez wzmacnianie mogłoby szkolić proces podejmowania decyzji na" +" podstawie otrzymywanych informacji zwrotnych. Kandydat przyjęty przez " +"określony sprawdzian daje nam konkretny wynik, a sekwencja prób pozwala " +"zaobserwować, ile pracy wymagało jego osiągnięcie." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"Istnieją już badania potwierdzające ten kierunek. {ph0}LLM4Decompile{ph1} " +"bada modele wyspecjalizowane w dekompilacji. {ph2}AutoDecompiler{ph3} " +"trenuje udoskonalanie w wielu turach, korzystając z informacji zwrotnych od " +"kompilatora i wykonania. Ich badania skupiają się na odzyskaniu funkcji. W " +"tej pracy użyłbym ich jako punktu wyjścia do powiązanego zadania " +"polegającego na znalezieniu źródła, które pasuje do danych wyjściowych " +"historycznego kompilatora." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"Aby jednak osiągnąć tak dobrze zdefiniowane zadanie, być może będziemy " +"musieli najpierw ustalić, jakie zasoby posiada funkcja, lub opracować nowy " +"sposób obserwowania zachowania programu podczas wykonania. Na przykład w " +"TH08 {ph0}różnica kolizji doprowadziła do tego, jak oryginalny program " +"obsługiwał obliczenia zmiennoprzecinkowe{ph1}. Zanim agent mógł przetestować" +" użyteczną korektę, musiał ustalić, co należy zmierzyć." + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "" +"Sugeruje to inną rolę modelu o szerokich możliwościach: przede wszystkim " +"pomoc w sprawdzeniu problemu. Gdy już to sprawdzimy, będziemy mogli " +"sprawdzić, jak daleko może zajść w tym przypadku wyuczona polityka " +"wyszukiwania." + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "Gdy osoba sprawdzająca myli się" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"Gdy używamy sprawdzania podczas uczenia, jego zakres staje się częścią " +"środowiska uczenia. Taki wzorzec lub moduł sprawdzający nazywam wyrocznią. " +"Nawet powtarzalną odpowiedź trzeba rozumieć w granicach tego, co " +"rzeczywiście sprawdza." + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"TH08 pokazał, jak wiele może ukryć się poza tym zasięgiem. Niektóre " +"zrekonstruowane funkcje przeszły dokładne porównania z nieprawidłowymi " +"stałymi zmiennoprzecinkowymi. Komparator korygował przeniesione adresy przed" +" sprawdzeniem instrukcji, ale sprawdzał wartości za tymi adresami tylko " +"wtedy, gdy zostały one wyraźnie zapisane w celu weryfikacji. Inne dosłowne " +"odniesienia można pominąć bez sprawdzania ich wartości." + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"Aby zaradzić tej luce, {ph0}szerszy audyt{ph1} wykrył nieprawidłowe stałe w " +"funkcjach, które przeszły już weryfikację. W jednym obliczeniu do " +"zrekonstruowanego kodu źródłowego dodano {ph2}, podczas gdy w oryginale " +"dodano {ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}Model nagrodzony starym testem weryfikacyjnym mógłby nauczyć się " +"tworzyć niepoprawną rekonstrukcję.{ph1} Nie trenowaliśmy modelu RL przy " +"użyciu tego modułu sprawdzającego. Niepowodzenie, które zaobserwowaliśmy, " +"dotyczyło samego sprawdzenia. Ale gdybyśmy użyli tego jako nagrody, ten sam " +"martwy punkt stałby się częścią środowiska uczenia się." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"Test funkcjonalny może mieć podobny martwy punkt. {ph0}Badania " +"wykorzystujące różnicowe rozmycie w dekompilatorach LLM{ph1} wykazały " +"różnice w zachowaniu poza dostarczonymi testami. Dlatego też musimy rozumieć" +" zdanie egzaminu w kategoriach przypadków, w których występuje. Podobnie " +"dopasowanie instrukcji należy rozumieć w kategoriach bajtów i danych, które " +"sprawdza." + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"Zanim użyję jakiegokolwiek rodzaju kontroli weryfikacyjnej jako nagrody, " +"przetestowałbym ją z celowo błędnymi wynikami. Chciałbym również, aby " +"ostateczna akceptacja była oddzielona od kodu źródłowego, który agent AI " +"może edytować. Model musi przejść weryfikację poprzez poprawną rekonstrukcję" +" programu. W przeciwnym razie zwykłe skopiowanie tablicy bajtów z celu może " +"oszukać naiwny system oceniania bez odzyskiwania przydatnego kodu " +"źródłowego." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "" +"{ph0}Ulepszanie modelu i ulepszanie jego modułu sprawdzającego należą do " +"tego samego problemu badawczego.{ph1} Im lepiej model optymalizuje " +"otrzymywaną informację zwrotną, tym ważniejsze jest zrozumienie tej " +"informacji." + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "Porównanie warte przeprowadzenia" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"Mając te kontrole, rozpocząłbym porównanie od ustalonej rodziny zadań VC7.1." +" Najpierw ustaliłbym podstawy dla silnego modelu sztucznej inteligencji " +"ogólnego przeznaczenia i mniejszego. Dodanie wiedzy o repozytorium do " +"mniejszego modelu pokazałoby, jakie zmiany w pobieraniu. Następnie " +"nadzorowana specjalizacja i wersja przeszkolona przez RL pozwolą nam " +"sprawdzić, co dodaje szkolenie." + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"Aby porównania te miały charakter informacyjny, każdy model otrzymałby te " +"same docelowe dowody i narzędzia. W przypadku porównań specyficznych dla " +"szkoleń zachowałbym również stały model podstawowy i dostępną wiedzę. " +"Powtarzane próby pomogłyby odróżnić niezawodną strategię wyszukiwania od " +"potencjalnego rozwiązania, które odniosło sukces przez przypadek." + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"Następnie oddzieliłbym dwa warunki początkowe: rekonstrukcję funkcji na " +"podstawie jej instrukcji i zamknięcie kilku ostatnich różnic w utrzymywanym " +"źródle. Wyspecjalizowany model sztucznej inteligencji może doskonale " +"sprawdzić się w drugim zadaniu, podczas gdy model sztucznej inteligencji " +"ogólnego przeznaczenia wykonuje większość pracy potrzebnej do jego " +"osiągnięcia. Zmierzenie ich osobno ujawniłoby ten podział pracy." + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"Obydwa zadania wymagają przykładów testowych wyłączonych ze szkolenia i " +"wyszukiwania. Powiązane gry Touhou udostępniają kod silnika. Wykluczenie " +"jednej gry z treningu może w dalszym ciągu pozostawić prawie identyczne " +"funkcje w zbiorze treningowym. Zamiast tego wykluczyłbym całe grupy " +"powiązanego kodu źródłowego i trzymał ich zweryfikowane odpowiedzi poza " +"danymi szkoleniowymi i biblioteką pobierania." + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"W przypadku tych przykładów wynikiem będą kompletne, niezależnie " +"zweryfikowane dopasowania. Równe budżety na propozycje kandydatów lub próby " +"kompilacji pomogłyby w porównaniu jakości wyszukiwania. Pomiar całkowitego " +"czasu i kosztów, w tym kompilacji, pokazałby, czy ta jakość zapewnia " +"efektywny przepływ pracy. Koszty szkoleń należy mierzyć osobno." + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"Obydwa pomiary mają znaczenie. Tania propozycja może prowadzić do " +"kosztownego przepływu pracy, jeśli powoduje więcej kompilacji, które nie " +"dostarczają żadnych przydatnych informacji. I odwrotnie, wolniejszy model " +"może być bardziej ekonomiczny, jeśli wcześniej znajdzie przydatny " +"eksperyment. Porównanie powinno uwzględniać te koszty." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"Liczenie zaakceptowanych wyników pozwala również zachować perspektywę " +"postępu pośredniego. Jeden TH09 {ph0}kandydat do zapisania powtórki{ph1} " +"wyglądał obiecująco, ponieważ skompilowana funkcja miała oczekiwany rozmiar," +" ale pełne porównanie nadal wykazało znaczne różnice. Zmiany w sposobie, w " +"jaki kompilator organizuje instrukcje, mogą również sprawić, że kandydat " +"wydaje się bliższy celowi bez rozwiązania podstawowego problemu. Taka " +"diagnostyka może pomóc w kolejnym eksperymencie, ale każdą nagrodę za " +"„zbliżenie się” porównałbym z pełną kontrolą akceptacji." + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"Byłbym zainteresowany wzorcem tych wyników. Jeśli wyspecjalizowany model " +"sztucznej inteligencji radzi sobie dobrze w znanej rodzinie kompilatorów, " +"czy ta zaleta przetrwa zmianę w zestawie narzędzi? A kiedy oba modele " +"sztucznej inteligencji będą dobrze odzyskiwane, ile jeszcze doda szkolenie? " +"Odpowiedzi pomogłyby nam zdecydować, gdzie każdy rodzaj modelu jest " +"najbardziej przydatny." + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "Jakiego rodzaju agenta AI to sugeruje?" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"Jeśli modele pomagają na różnych etapach, przydatny może być agent ogólny z " +"dostępem do modelu specjalistycznego. Gdy zadanie sprowadza się do znanego " +"problemu z kompilatorem, może poprosić specjalistę o kandydatów. Jeśli " +"wyniki przestają mieć sens, agent ogólny może wrócić do danych celu albo " +"zbadać sam pomiar." + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "" +"W takim układzie specjalizacja staje się narzędziem, które agent może wybrać" +" w miarę rozwoju dochodzenia. Agent zachowuje swobodę zmiany kierunku, co " +"umożliwiło wcześniejsze przełomy." + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"Wynika to naturalnie z przemian w przemyśle, które opisałem w poprzednim " +"eseju. Możliwość przeprowadzenia znacznie większej liczby eksperymentów " +"zmienia sposób organizacji pracy. Daje nam to również powód, aby zadać sobie" +" pytanie, które decyzje wymagają szerokiego osądu, a które można poprawić " +"dzięki wielokrotnemu doświadczeniu z konkretnym rzemiosłem." + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"Na razie najsilniejszy model ogólny zasłużył na miejsce w moim przepływie " +"pracy, rozwiązując problemy, których wcześniej nie rozwiązałem. Te sukcesy " +"skłaniają mnie do zbadania procesu: jaka część zależała od szerokości jego " +"możliwości, a jaką mógłby wykonać model uczony specjalnie do takiej " +"rekonstrukcji?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "" +"{ph0}Repozytoria umożliwiają nam przetestowanie pytania.{ph1} Chciałbym użyć" +" tego rekordu do stworzenia porównania i zobaczenia, czego się dowiemy." + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "Dowody i modelowe przypisanie" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"Przykłady opisują historyczne porównania poziomów funkcji zarejestrowane w " +"połączonych zatwierdzeniach. Sprawdzanie czasu działania całej gry to osobne" +" kamienie milowe. Dokumenty źródłowe i pasujące sprawdzono 13 października " +"2026 r." + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"Etykieta TH09 {ph0} oznacza GPT-6-Astra. Model powiązany z {ph1} zmieniał " +"się z biegiem czasu, więc sama etykieta nie może zidentyfikować modelu " +"użytego w konkretnym przebiegu. Wyraźne nazwy modeli w innych cytowanych " +"zatwierdzeniach zapewniają zarejestrowaną atrybucję. Historie te nie " +"obejmują spójnych pomiarów kosztów i wysiłku dla każdego przebiegu." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "" +"{ph0}TH09 okresy istnienia obiektów tymczasowych:{ph1} {ph2}wcześniejszy " +"przegląd kontekstu{ph3} i {ph4}pełna rekonstrukcja zweryfikowana przez " +"czystą rekompilację ze źródła{ph5}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"{ph0}Callback Front w TH09:{ph1} {ph2}obszary diagnostyczne bez pełnej " +"zgodności{ph3}, {ph4}nowy graf przepływu sterowania Astry{ph5} i " +"{ph6}zaakceptowane sprawdzenie ponownej kompilacji{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}Wiedza o kompilatorze:{ph1} {ph2}ponowne użycie zachowania grup " +"identyfikatorów w TH095{ph3}, {ph4}kod gracza TH04 i kolejność " +"linkowania{ph5} oraz {ph6}pełna rekonstrukcja funkcji tworzenia przeciwników" +" TH09 przez Lunę{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}Kontrola i diagnostyka:{ph1} {ph2}TH08 audyt stałej " +"zmiennoprzecinkowej{ph3}, {ph4}TH08 badanie numeryczne{ph5} i {ph6}TH09 " +"rekonstrukcja z zachowaniem powtórki{ph7}." + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "" +"Proponowane porównania wyspecjalizowanych modeli i szkolenia RL to przyszłe " +"eksperymenty. Motywują ich historie projektów. Na potrzeby tego eseju nie " +"oceniano żadnego wyszkolonego specjalistycznego modelu." + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "Czy inżynieria odwrotna potrzebuje większego modelu? | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "" +"Czego rekonstrukcja Touhou nauczyła mnie o modelach ogólnych, modelach " +"specjalistycznych i nauce proponowania lepszych hipotez na podstawie " +"informacji zwrotnych od kompilatora." + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "Na tej stronie" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "Modele i esej o inżynierii odwrotnej" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "Wybrane eksperymenty rekonstrukcyjne" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "Do góry" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "" +"{ph0}Szczegółowe notatki o dowodach{ph1} zawierają zapisane porównania i " +"kontekst eksperymentów." + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "Autor: N0zoM1z0 · 13 października 2026 · Szkic do przejrzenia" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "Instrukcja instalacji" diff --git a/website/locales/pt-BR/messages.po b/website/locales/pt-BR/messages.po index a0741271d..c1e2d5d2b 100644 --- a/website/locales/pt-BR/messages.po +++ b/website/locales/pt-BR/messages.po @@ -32,18 +32,18 @@ msgid "Thoughts on reverse engineering." msgstr "Reflexões sobre engenharia reversa." #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "Reconstrução do jogo{ph0}Ensaio" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "A Revolução industrial na engenharia reversa" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " @@ -52,19 +52,20 @@ msgstr "" "O manual RE e reconstrução TH08, TH095 e TH04 me ensinou sobre agentes, " "verificação e conhecimento que compostos entre projetos." -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "Leia o artigo" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "Por N0zoM1z0 * 10 de outubro de 2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -100,6 +101,8 @@ msgstr "" "agentes REA e AI." #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -136,6 +139,7 @@ msgstr "" "codificação." #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -156,6 +160,7 @@ msgid "REA home" msgstr "Página inicial do REA" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -176,6 +181,7 @@ msgid "Main navigation" msgstr "Navegação principal" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -196,6 +202,7 @@ msgid "REA on GitHub" msgstr "REA no GitHub" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -216,6 +223,7 @@ msgid "Join REA on Discord" msgstr "Participe do Discord do REA" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -235,7 +243,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "Siga o REA no X" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "Voltar ao topo" @@ -11695,6 +11703,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "Mesmo espaçamento: 256 16 = 16 unidades angulares = 22,5" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -11715,6 +11724,7 @@ msgid "Showcases" msgstr "Casos práticos" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -11735,6 +11745,7 @@ msgid "Blog" msgstr "Blog" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -11755,6 +11766,7 @@ msgid "Get started" msgstr "Começar" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -11774,7 +11786,8 @@ msgctxt "shared" msgid "Guides" msgstr "Guias" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -11794,7 +11807,8 @@ msgctxt "shared" msgid "Source" msgstr "Código-fonte" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -11814,7 +11828,8 @@ msgctxt "shared" msgid "MIT license" msgstr "Licença MIT" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -11834,7 +11849,8 @@ msgctxt "shared" msgid "Join the community" msgstr "Participe da comunidade" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -12798,6 +12814,1386 @@ msgstr "" "servidor MCP do Everywhere para inspecionar o tráfego capturado com seu " "agente." +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "Modelos especializados{ph0}Ensaio" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "A engenharia reversa precisa de um modelo maior?" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "" +"O que a reconstrução de Touhou sugere sobre modelos gerais, modelos " +"especializados e o aprendizado com o retorno do compilador." + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Por N0zoM1z0 · 13 de outubro de 2026" + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "Ir para o conteúdo" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "" +"{ph0}Página inicial{ph1} / {ph2}Blog{ph3} / Modelos e engenharia reversa" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "Ensaio" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "A engenharia reversa precisa de um modelo maior?" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Por N0zoM1z0 · 13 de outubro de 2026" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "Pontos principais" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "" +"{ph0}A capacidade do modelo afeta quais hipóteses um agente de IA pode " +"propor.{ph1} Sessões posteriores resolveram problemas que trabalhos " +"anteriores haviam deixado sem solução." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "" +"{ph0}Um compilador familiar oferece padrões concretos para um modelo " +"especializado aprender.{ph1} Algumas correspondências exatas de código de " +"máquina dependem de padrões de código-fonte específicos e reutilizáveis." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "" +"{ph0}Inclua o conhecimento do repositório em uma comparação justa.{ph1} Um " +"modelo menor com boa recuperação de conhecimento pode já ter informações " +"suficientes para progredir." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "" +"{ph0}Treine o modelo para escolher o próximo experimento útil e teste seu " +"verificador.{ph1} O feedback é útil apenas na medida em que o verificador " +"verifica as coisas certas." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "" +"{ph0}Avalie os resultados verificados da reconstrução juntamente com o tempo" +" e o custo.{ph1} É isso que quero medir para o fluxo de trabalho completo do" +" agente de IA." + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "Neste artigo" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}O que os modelos mais capazes mudaram{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}Por que se especializar?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}Onde essa experiência deve ser armazenada?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}Aprendendo o próximo experimento útil{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}Engenharia reversa e aprendizagem por reforço{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}Quando o verificador está errado{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}Uma comparação que vale a pena fazer{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}Que tipo de agente de IA isso sugere?{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "O que os modelos mais capazes mudaram" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"Desde agosto de 2026 venho explorando o quanto de engenharia reversa um " +"agente pode realizar com acesso a um programa e uma forma de verificar seu " +"funcionamento. A maior parte da minha experiência vem da reconstrução de " +"jogos, especialmente Touhou. Como mudei de modelo, os repositórios " +"mantiveram um registro do que cada sessão conseguiu recuperar." + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"Grande parte desse trabalho visa a reconstrução exata: compilamos a fonte " +"mantida sob um conjunto de ferramentas histórico com versões fixas e " +"verificamos se ela reproduz a função alvo. Quando um modelo posterior é bem-" +"sucedido onde o trabalho anterior estagnou, as mudanças na origem mostram o " +"que tornou esse progresso possível." + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "As variáveis temporárias precisavam de vidas sobrepostas" + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"Grande parte da lógica da função de ataque TH09 já havia sido reconstruída, " +"mas o compilador ainda armazenava resultados temporários de maneira " +"diferente do original. O problema restante era quanto tempo esses resultados" +" precisavam para permanecer vivos e quando seu armazenamento poderia ser " +"reutilizado." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"Um {ph0}GPT-6-Sol registro de sessão{ph1} relatou essa incompatibilidade " +"após testar vários arranjos comuns de código-fonte. Quando {ph2}GPT-6.1-Sol " +"examinou o problema novamente{ph3}, propôs uma hipótese útil sobre o tempo " +"de vida dessas variáveis ​​temporárias." + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"A função produziu resultados temporários e os copiou em posições de " +"animação. Em C++, um resultado temporário permanece ativo até que a " +"expressão que o utiliza termine. O agrupamento das operações reais em uma " +"expressão manteve esses resultados vivos juntos, de modo que o compilador " +"não pudesse mais reutilizar o mesmo armazenamento para todos eles." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"Um resultado ainda compartilha o armazenamento com um valor usado " +"posteriormente para verificações de colisão. Dar a esse valor seu próprio " +"tempo de vida resolveu a sobreposição restante. Após vários experimentos " +"direcionados, {ph0}uma recompilação limpa da fonte confirmou que a função " +"completa correspondia a{ph1}." + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"Estou interessado em saber como a descoberta e os testes se apoiaram. A " +"hipótese sobre a vida útil dos objetos temporários deu ao agente de IA uma " +"nova direção. O feedback do compilador ajudou a refinar essa hipótese em um " +"arranjo de código-fonte correspondente." + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "Um gráfico de fluxo de controle diferente" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"Uma segunda função TH09 mostra por que essa nova direção pode ser " +"importante. Aqui, o obstáculo foi a forma como diversas filiais " +"compartilharam seu trabalho final. O trabalho anterior de " +"{ph0}GPT-6.1-Sol{ph1} fez com que partes da função correspondessem, mas as " +"ramificações ainda se uniram de maneira diferente do original." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}GPT-6-Astra alterou o gráfico de fluxo de controle circundante{ph1}. Os" +" principais caminhos levaram agora a uma atualização e retorno final " +"partilhado. Nessa estrutura de origem, o compilador combinou as ramificações" +" da mesma forma que o original. A função completa correspondeu e uma " +"{ph2}verificação de reconstrução separada confirmou isso{ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}Mudar a representação abriu um espaço de pesquisa mais produtivo.{ph1} " +"Ambos os casos me dão um motivo para levar a sério a capacidade geral do " +"modelo: um agente pode continuar tentando variações locais por um longo " +"tempo antes de encontrar uma maneira melhor de expressar o trabalho " +"circundante." + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"As sessões posteriores também herdaram o código anterior e os experimentos " +"fracassados já registrados. Esse trabalho acumulado fazia parte da vantagem " +"delas. O histórico permite examinar as descobertas e suas verificações; uma " +"comparação controlada ajudaria a separar o efeito do modelo do efeito da " +"experiência herdada." + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"É isso que torna a questão interessante para mim. Algum progresso veio da " +"descoberta de uma nova representação. Grande parte do trabalho restante " +"envolveu testar diferentes arranjos de código-fonte em um compilador " +"familiar. Quanto disso requer ampla capacidade de raciocínio? Quanto um " +"modelo poderia aprender trabalhando repetidamente com esse compilador e " +"código?" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "Por que um modelo especializado de IA pode funcionar bem?" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"Touhou nos dá uma razão concreta para esperar que essa experiência ajude. " +"Grande parte do código do jogo vem do mesmo autor, ZUN, portanto, hábitos " +"recorrentes são uma suposição inicial razoável. Os repositórios apoiam isso " +"com exemplos úteis: loops relacionados e arranjos auxiliares forneceram " +"hipóteses em todos os jogos." + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "" +"Esses padrões de origem tornam-se mais específicos quando incluímos o " +"compilador. Sob uma determinada versão e conjunto de opções, pequenas " +"alterações na fonte podem produzir diferenças repetíveis no código de " +"máquina. Algumas dessas diferenças são surpreendentemente obscuras." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"Em TH095, por exemplo, {ph0}até mesmo o nome de uma variável local pode " +"afetar o local onde VC7.1 a armazenou{ph1}. Mover sua declaração não " +"resolveu o layout de armazenamento. No entanto, uma função anterior revelou " +"um padrão de nomenclatura que afetou a escolha do compilador. Isso sugeriu " +"uma hipótese mais promissora para {ph2}reconstruir {ph3}{ph4}." + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "" +"A reutilização desse padrão para a variável de tamanho de arquivo produziu o" +" layout necessário sem adicionar armazenamento. A função completa então " +"correspondeu." + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "" +"Este é um detalhe muito específico que um modelo de IA de uso geral pode não" +" saber quando encontra o problema pela primeira vez. Um modelo especializado" +" para este compilador poderia ver muitos desses casos e aprender quais " +"variações do código-fonte valem a pena testar primeiro." + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"A oportunidade é especialmente clara em problemas de correspondência final " +"onde já entendemos o comportamento. Estamos então perguntando qual arranjo " +"comum de código-fonte este compilador transforma nas instruções observadas. " +"A especialização poderia ajudar o modelo a propor essas formas de forma mais" +" eficiente, enquanto o alvo ainda determina quais hipóteses sobreviverão." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"Padrões úteis devem manter seu contexto. TH08 usa uma versão Visual C++ " +"anterior a TH095 e TH09. TH04 usa um compilador diferente da era DOS. Sua " +"{ph0}reconstrução do código do jogador{ph1} precisava de diferentes " +"hipóteses sobre os padrões do código-fonte e como o código compilado era " +"vinculado a um executável. Ter o mesmo autor nos dá uma expectativa inicial," +" mas cada alvo nos diz se se aplica. Um modelo especializado precisaria " +"distinguir esses contextos." + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "Onde essa experiência deve ser armazenada?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"Antes de decidir ensinar esses padrões por meio do treinamento de modelos, " +"eu examinaria o conhecimento que já mantemos no repositório. No {ph0}ensaio " +"anterior{ph1}, escrevi sobre isso se tornar a memória de trabalho do " +"projeto. Essa memória inclui lições de compilador, juntamente com a fonte e " +"os experimentos fracassados ​​que os tornaram úteis." + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"Ao recuperar esse registro, um agente pode começar com um resultado " +"conhecido e inspecionar como o alcançamos. Também pode evitar alternativas " +"que já falharam no mesmo contexto. O ponto inicial melhora sem alterar os " +"parâmetros treinados do modelo." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"Ao reconstruir a função de TH09 para criar inimigos, uma {ph0}sessão " +"GPT-6-Luna-max{ph1} tirou uma hipótese do código-fonte TH08 relacionado. " +"Esse código anterior sugeria como organizar o loop e lidar com falhas dentro" +" dele. As próprias evidências de TH09 forneceram detalhes específicos do " +"jogo. As reconstruções da fonte confirmaram que a função completa " +"correspondia." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}\"O modelo não sabia daquela peculiaridade do compilador\" e \"o modelo" +" não pôde usá-lo\" são problemas diferentes.{ph1} A recuperação pode " +"resolver o primeiro, mas transformar esse fato em um candidato útil ainda dá" +" trabalho. E se o código-fonte candidato falhar, o modelo deverá decidir o " +"que o resultado significa para sua próxima tentativa. Conhecer o padrão " +"relevante é apenas o começo desse processo." + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"Por esse motivo, eu incluiria um modelo menor de IA de uso geral com boa " +"recuperação em qualquer comparação. Fornecer a mesma biblioteca de " +"experiência nos ajudaria a identificar o que o treinamento agrega: melhor " +"geração de candidatos, melhores decisões após feedback ou ambos." + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "Aprendendo o próximo experimento útil" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"Essas decisões após feedback são o que eu mais gostaria de estudar. Na " +"reconstrução agente, o modelo propõe uma explicação e a testa em relação ao " +"programa. Mesmo quando o código-fonte candidato falha, o resultado pode " +"restringir as possibilidades restantes e sugerir um próximo experimento mais" +" útil." + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "" +"Considere novamente o exemplo dos resultados temporários. Sua fonte final " +"mostra o arranjo que funcionou, mas o caminho para essa fonte contém mais " +"informações. Cada um dos experimentos a seguir ajudou a identificar o que " +"ainda precisava ser mudado." + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "Experimentar" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "O que seu resultado nos ensinou" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "Tente uma maneira diferente de copiar os resultados" + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "O código de cópia muda, mas a função ainda é diferente." + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "Use os valores retornados diretamente" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "" +"A cópia segue o padrão original, mas o armazenamento temporário ainda é " +"diferente." + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "Mantenha todas as variáveis temporárias válidas ao mesmo tempo" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "" +"Eles obtêm armazenamento separado, mas ainda se sobrepõe a um valor usado " +"posteriormente para verificações de colisão." + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "Mantenha o valor de verificação de colisão separado" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "Uma recompilação limpa da fonte confirma a correspondência completa." + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "" +"Experimentos selecionados da reconstrução da função de ataque acima, " +"agrupados pelo que nos ensinaram." + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"Um registro de treinamento que mantenha essa sequência pode ensinar mais do " +"que apenas a fonte final. Ele conecta cada mudança proposta a um resultado " +"observado e à próxima decisão. Manter variações ineficazes também é " +"importante: elas informam a um agente posterior quais hipóteses já foram " +"testadas naquele contexto." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}Eu gostaria que o modelo aprendesse como usar o feedback.{ph1} Um " +"resultado neutro é um motivo para reconsiderar a variação; uma " +"incompatibilidade alterada pode apontar para outra causa. Quando as edições " +"locais deixarem de ser informativas, o agente deverá ser capaz de revisitar " +"a representação da fonte ou inspecionar as evidências novamente." + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"Aprender a fazer essas escolhas requer autonomia. Às vezes, o próximo passo " +"útil é inspecionar outro chamador em vez de compilar outra edição. Uma " +"sequência rígida de reescritas necessárias eliminaria essa escolha, " +"juntamente com parte do comportamento que queremos que o modelo aprenda." + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "" +"Por que a engenharia reversa é interessante para aprendizagem por reforço" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"Uma reconstrução com escopo definido oferece um ambiente prático para " +"estudar essas escolhas. Com as versões do alvo e do compilador fixadas, " +"muitos experimentos de código-fonte dão feedback rápido e repetível. O " +"agente pode compilar um candidato, examinar as diferenças e escolher o " +"próximo passo." + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"A aprendizagem por reforço poderia treinar esse processo de tomada de " +"decisão por meio do feedback que recebe. Um candidato aceito por meio de uma" +" verificação definida nos dá um resultado concreto, enquanto a sequência de " +"tentativas nos permite observar quanto trabalho foi necessário para alcançá-" +"lo." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"Já existem pesquisas apoiando essa direção. {ph0}LLM4Decompile{ph1} estuda " +"modelos especializados para descompilação. {ph2}AutoDecompiler{ph3} treina o" +" refinamento em várias rodadas usando feedback do compilador e de execução. " +"Seus estudos se concentram na recuperação funcional. Para este trabalho, eu " +"os usaria como ponto de partida para a tarefa relacionada de encontrar uma " +"fonte que corresponda à saída de um compilador histórico." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"Porém, para alcançar uma tarefa tão bem definida, talvez precisemos primeiro" +" estabelecer quais recursos uma função possui ou criar uma nova forma de " +"observar o comportamento do programa durante a execução. Em TH08, por " +"exemplo, uma {ph0}diferença de colisão levou de volta à forma como o " +"programa original lidava com cálculos de ponto flutuante{ph1}. Antes que o " +"agente pudesse testar uma correção útil, ele precisava decidir o que medir." + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "" +"Isto sugere outro papel para um modelo amplamente capaz: em primeiro lugar, " +"ajudar a tornar o problema verificável. Uma vez que essa verificação exista," +" podemos investigar até onde uma política de pesquisa aprendida pode chegar " +"com ela." + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "Quando o verificador está errado" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"Quando usamos uma verificação no treinamento, sua cobertura passa a fazer " +"parte do ambiente de aprendizagem. Chamo essa referência ou verificador de " +"oracle. Mesmo uma resposta repetível precisa ser entendida pelos aspectos " +"que ela realmente verifica." + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"TH08 mostrou o quanto pode se esconder fora dessa cobertura. Algumas funções" +" reconstruídas passaram em suas comparações exatas com constantes flutuantes" +" erradas. O comparador ajustou os endereços realocados antes de verificar as" +" instruções, mas verificou os valores por trás desses endereços somente " +"quando eles foram explicitamente registrados para verificação. Outras " +"referências literais poderiam passar sem que seus valores fossem examinados." + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"Para resolver essa lacuna, uma {ph0}auditoria mais ampla{ph1} encontrou " +"constantes incorretas em funções que já haviam passado na verificação. Em um" +" cálculo, o código-fonte reconstruído adicionou {ph2}, enquanto o original " +"adicionou {ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}Um modelo recompensado pela verificação antiga poderia aprender a " +"produzir uma reconstrução incorreta.{ph1} Não treinamos um modelo RL usando " +"esse verificador. A falha que observamos estava na própria verificação. Mas " +"se usássemos isso como recompensa, o mesmo ponto cego passaria a fazer parte" +" do ambiente de aprendizagem." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"Um teste funcional pode ter um ponto cego semelhante. {ph0}Pesquisas usando " +"difusão diferencial em descompiladores LLM{ph1} encontraram diferenças " +"comportamentais fora dos testes fornecidos. Portanto, precisamos entender um" +" teste aprovado em termos dos casos que ele exerce. Da mesma forma, uma " +"correspondência de instrução deve ser entendida em termos dos bytes e dos " +"dados que ela verifica." + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"Antes de usar qualquer tipo de verificação como recompensa, eu testaria com " +"resultados deliberadamente incorretos. Eu também manteria a aceitação final " +"separada do código-fonte que o agente de IA pode editar. O modelo deve " +"passar na verificação reconstruindo o programa corretamente. Caso contrário," +" simplesmente copiar uma matriz de bytes do destino poderia enganar um " +"sistema de pontuação ingênuo sem recuperar o código-fonte útil." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "" +"{ph0}Aprimorar o aluno e melhorar seu verificador pertencem ao mesmo " +"problema de pesquisa.{ph1} À medida que o aluno melhora na otimização do " +"feedback que lhe damos, compreender esse feedback também se torna mais " +"importante." + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "Uma comparação que vale a pena fazer" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"Com essas verificações implementadas, eu iniciaria a comparação em uma " +"família de tarefas fixa VC7.1. Primeiro, eu estabeleceria linhas de base " +"para um modelo forte de IA de uso geral e um modelo menor. Adicionar " +"conhecimento do repositório ao modelo menor mostraria quais mudanças na " +"recuperação. A partir daí, a especialização supervisionada e uma versão " +"treinada em RL nos permitiriam examinar o que o treinamento acrescenta." + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"Para tornar essas comparações informativas, cada modelo receberia as mesmas " +"evidências e ferramentas alvo. Para comparações específicas de treinamento, " +"eu também manteria o modelo base e o conhecimento disponível fixos. Testes " +"repetidos ajudariam a distinguir uma estratégia de busca confiável de uma " +"solução candidata que tivesse sucesso por acaso." + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"Eu separaria então duas condições iniciais: reconstruir uma função a partir " +"de suas instruções e fechar as últimas diferenças na fonte mantida. Um " +"modelo de IA especializado pode ser excelente na segunda tarefa, enquanto um" +" modelo de IA de uso geral faz grande parte do trabalho necessário para " +"alcançá-la. Medi-los separadamente revelaria essa divisão de trabalho." + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"Ambas as tarefas precisam de exemplos de teste excluídos do treinamento e " +"recuperação. Jogos Touhou relacionados compartilham o código do mecanismo. " +"Excluir um jogo do treinamento ainda poderia deixar funções quase idênticas " +"no conjunto de treinamento. Em vez disso, eu excluiria grupos inteiros de " +"código-fonte relacionado e manteria suas respostas verificadas fora dos " +"dados de treinamento e da biblioteca de recuperação." + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"Para estes exemplos, o resultado seria correspondências completas e " +"verificadas de forma independente. Orçamentos iguais para propostas de " +"candidatos ou tentativas de compilação ajudariam a comparar a qualidade da " +"pesquisa. Medir o tempo e o custo totais, incluindo a compilação, mostraria " +"se essa qualidade produz um fluxo de trabalho eficiente. Os custos de " +"formação devem ser medidos separadamente." + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"Ambas as medidas são importantes. Uma proposta barata pode levar a um fluxo " +"de trabalho caro se causar mais compilações que não fornecem informações " +"úteis. Por outro lado, um modelo mais lento pode ser mais econômico se " +"encontrar uma experiência útil mais cedo. A comparação deve incluir esses " +"custos." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"A contagem dos resultados aceitos também mantém o progresso intermediário em" +" perspectiva. Um TH09 {ph0}candidato para salvar repetição{ph1} parecia " +"promissor porque a função compilada tinha o tamanho esperado, mas uma " +"comparação completa ainda encontrou diferenças substanciais. Mudanças na " +"forma como o compilador organiza as instruções também podem fazer o " +"candidato parecer mais próximo do alvo, sem resolver o problema subjacente. " +"Esses diagnósticos podem orientar o próximo experimento, mas eu validaria " +"qualquer recompensa por “chegar mais perto” em relação à verificação de " +"aceitação total." + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"Eu estaria interessado no padrão desses resultados. Se um modelo de IA " +"especializado funciona bem em uma família de compiladores familiar, essa " +"vantagem sobreviverá a uma mudança no conjunto de ferramentas? E uma vez que" +" ambos os modelos de IA tenham uma boa recuperação, quanto o treinamento " +"ainda acrescenta? As respostas nos ajudariam a decidir onde cada tipo de " +"modelo é mais útil." + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "Que tipo de agente de IA isso sugere?" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"Se os modelos acabarem por ajudar em diferentes fases, um acordo útil poderá" +" ser um agente amplo com acesso a um modelo de IA especializado. Depois que " +"uma tarefa se torna uma pesquisa familiar do compilador, ela pode solicitar " +"candidatos ao modelo de IA especializado. Se os resultados deixarem de fazer" +" sentido, o agente mais amplo poderá retornar à evidência alvo ou investigar" +" a própria medição." + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "" +"Nesse arranjo, a especialização torna-se uma ferramenta que o agente pode " +"escolher à medida que a investigação se desenvolve. O agente mantém a " +"liberdade de mudar a direção que tornou possíveis os avanços anteriores." + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"Isto decorre naturalmente da mudança industrial que descrevi no ensaio " +"anterior. Ser capaz de realizar muito mais experimentos muda a forma como " +"organizamos o trabalho. Também nos dá uma razão para perguntar quais " +"decisões necessitam de um julgamento amplo e quais melhoram através da " +"experiência repetida com uma determinada arte." + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"Por enquanto, o modelo geral mais forte conquistou seu lugar no meu trabalho" +" ao resolver problemas que eu havia deixado em aberto. Esses sucessos me " +"fazem querer estudar o processo: quanto dependia da amplitude do modelo e " +"quanto poderia ser feito por um modelo treinado especificamente para esse " +"tipo de reconstrução?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "" +"{ph0}Os repositórios nos fornecem uma maneira de testar a pergunta.{ph1} " +"Gostaria de usar esse registro para construir a comparação e ver o que " +"aprendemos." + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "Evidências e atribuição de modelo" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"Os exemplos descrevem comparações históricas em nível de função registradas " +"nos commits vinculados. As verificações de tempo de execução de todo o jogo " +"são marcos separados. Os registros de origem e correspondentes foram " +"revisados em 13 de outubro de 2026." + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"O rótulo TH09 {ph0} significa GPT-6-Astra. O modelo associado a {ph1} mudou " +"ao longo do tempo, de modo que o rótulo por si só não consegue identificar o" +" modelo usado em uma execução específica. Nomes de modelos explícitos nos " +"outros commits citados fornecem a atribuição registrada. Esses históricos " +"não incluem medições consistentes de custo ou esforço para cada execução." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "" +"{ph0}TH09 tempos de vida do objeto temporário:{ph1} a {ph2}revisão de " +"contexto anterior{ph3} e a {ph4}reconstrução completa verificada por uma " +"recompilação limpa da origem{ph5}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"{ph0}TH09 Front retorno de chamada:{ph1} {ph2}regiões de diagnóstico que não" +" correspondem{ph3}, {ph4}novo gráfico de fluxo de controle de Astra{ph5} e " +"sua {ph6}verificação de recompilação aceita{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}Conhecimento do compilador:{ph1} {ph2}TH095 reutilização do " +"comportamento do bloco de identificadores{ph3}, {ph4}TH04 código-fonte do " +"jogador e ordem do vinculador{ph5} e {ph6}reconstrução completa de Luna da " +"função de criação de inimigo de TH09{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}Verificações e diagnósticos:{ph1} {ph2}TH08 auditoria de constante de " +"ponto flutuante{ph3}, {ph4}TH08 investigação numérica{ph5} e {ph6}TH09 " +"reconstrução para salvar replay{ph7}." + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "" +"As comparações propostas de modelos especializados e treinamento RL são " +"experimentos futuros. As histórias do projeto os motivam. Nenhum modelo " +"especializado treinado foi avaliado para este ensaio." + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "A engenharia reversa precisa de um modelo maior? | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "" +"O que a reconstrução Touhou me ensinou sobre modelos gerais, modelos " +"especializados e como aprender a propor melhores hipóteses a partir do " +"feedback do compilador." + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "Nesta página" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "Modelos e ensaio de engenharia reversa" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "Experimentos de reconstrução selecionados" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "Voltar ao topo" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "" +"As {ph0}notas detalhadas de evidências{ph1} incluem as comparações " +"registradas e o contexto dos experimentos." + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "Por N0zoM1z0 · 13 de outubro de 2026 · Rascunho para revisão" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "Guia de instalação" diff --git a/website/locales/ru/messages.po b/website/locales/ru/messages.po index 9f0486916..32b973c33 100644 --- a/website/locales/ru/messages.po +++ b/website/locales/ru/messages.po @@ -32,18 +32,18 @@ msgid "Thoughts on reverse engineering." msgstr "Мысли о реверс-инжиниринге." #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "Реконструкция игры{ph0}Сочинение" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "Промышленная революция в области реверс-инжиниринга" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " @@ -52,19 +52,20 @@ msgstr "" "Чему меня научило руководство по обновлению и реконструкции TH08, TH095 и " "TH04 об агентах, проверке и знаниях, которые используются в разных проектах." -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "Прочтите статью" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "Автор: N0zoM1z0 · 10 октября 2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -100,6 +101,8 @@ msgstr "" "REA и агентами искусственного интеллекта." #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -136,6 +139,7 @@ msgstr "" " с помощью вашего программиста." #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -156,6 +160,7 @@ msgid "REA home" msgstr "Главная REA" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -176,6 +181,7 @@ msgid "Main navigation" msgstr "Основная навигация" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -196,6 +202,7 @@ msgid "REA on GitHub" msgstr "REA на GitHub" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -216,6 +223,7 @@ msgid "Join REA on Discord" msgstr "Присоединиться к REA в Discord" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -235,7 +243,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "Подписаться на REA в X" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "Наверх" @@ -11732,6 +11740,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "Одинаковое расстояние: 256 ÷ 16 = 16 угловых единиц = 22,5°" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -11752,6 +11761,7 @@ msgid "Showcases" msgstr "Примеры" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -11772,6 +11782,7 @@ msgid "Blog" msgstr "Блог" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -11792,6 +11803,7 @@ msgid "Get started" msgstr "Начать" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -11811,7 +11823,8 @@ msgctxt "shared" msgid "Guides" msgstr "Руководства" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -11831,7 +11844,8 @@ msgctxt "shared" msgid "Source" msgstr "Исходный код" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -11851,7 +11865,8 @@ msgctxt "shared" msgid "MIT license" msgstr "Лицензия MIT" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -11871,7 +11886,8 @@ msgctxt "shared" msgid "Join the community" msgstr "Вступить в сообщество" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -12840,6 +12856,1385 @@ msgstr "" "подключите MCP-сервер Everywhere, чтобы исследовать записанный трафик вместе" " с агентом." +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "Специализация моделей{ph0}Эссе" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "Нужна ли для обратной разработки более крупная модель?" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "" +"Что реконструкция Touhou помогает понять об универсальных и " +"специализированных моделях и обучении на обратной связи от компилятора." + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Автор N0zoM1z0 · 13 октября 2026 г." + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "Перейти к содержанию" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "" +"{ph0}Главная страница{ph1} / {ph2}Блог{ph3} / Модели и реверс-инжиниринг" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "Эссе" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "Нужна ли реверс-инжинирингу модель большего размера?" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Автор N0zoM1z0 · 13 октября 2026 г." + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "Главное" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "" +"{ph0}Возможности модели влияют на то, какие гипотезы может предложить ИИ-" +"агент.{ph1} На последующих занятиях решались проблемы, которые ранее " +"оставались нерешенными." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "" +"{ph0}Знакомый компилятор предлагает конкретные шаблоны для изучения " +"специализированной модели.{ph1} Некоторые точные совпадения машинного кода " +"зависят от конкретных многократно используемых шаблонов исходного кода." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "" +"{ph0}Включите знания репозитория в справедливое сравнение.{ph1} Меньшая " +"модель с хорошим извлечением знаний может уже иметь достаточно информации " +"для достижения прогресса." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "" +"{ph0}Обучите модель выбирать следующий полезный эксперимент и протестируйте " +"ее средство проверки.{ph1} Обратная связь полезна только в той степени, в " +"которой средство проверки проверяет правильные вещи." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "" +"{ph0}Оцените проверенные результаты реконструкции, а также время и " +"стоимость.{ph1} Это то, что я хочу измерить для всего рабочего процесса ИИ-" +"агента." + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "В этой статье" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}Что изменили более сильные модели{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}Зачем специализироваться?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}Где следует хранить этот опыт?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}Изучаем следующий полезный эксперимент{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}Обратное проектирование и обучение с подкреплением{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}Когда программа проверки ошибается{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}Сравнение, которое стоит провести{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}О каком ИИ-агенте идет речь?{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "Что изменили более сильные модели" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"С августа 2026 года я изучаю, какой объем реверс-инжиниринга может провести " +"агент, имея доступ к программе и способ проверки ее работы. Большая часть " +"моего опыта связана с реконструкцией игр, особенно Touhou. Поскольку я менял" +" модели, в репозиториях фиксировалось, что удалось восстановить в каждом " +"сеансе." + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"Большая часть этой работы направлена на точную реконструкцию: мы компилируем" +" поддерживаемый исходный код с помощью исторической цепочки инструментов с " +"фиксированными версиями и проверяем, воспроизводит ли он целевую функцию. " +"Когда более поздняя модель оказывается успешной там, где предыдущие работы " +"застопорились, изменения в исходном коде показывают, что сделало этот " +"прогресс возможным." + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "Временным переменным требовалось перекрывающееся время жизни." + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"Большая часть логики функции атаки TH09 уже была реконструирована, но " +"компилятор по-прежнему сохранял временные результаты иначе, чем оригинал. " +"Оставшаяся проблема заключалась в том, как долго эти результаты должны " +"оставаться живыми и когда их хранилище можно будет использовать повторно." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"Запись сеанса {ph0}GPT-6-Sol{ph1} сообщила об этом несоответствии после " +"тестирования нескольких обычных схем исходного кода. Когда {ph2}GPT-6.1-Sol " +"снова изучил проблему{ph3}, он предложил полезную гипотезу о времени жизни " +"этих временных переменных." + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"Функция выдавала временные результаты и копировала их в позиции анимации. В " +"C++ временный результат остается активным до тех пор, пока выражение, " +"использующее его, не завершится. Группировка реальных операций в одно " +"выражение сохраняла эти результаты вместе, поэтому компилятор больше не мог " +"повторно использовать одно и то же хранилище для всех них." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"Один из результатов по-прежнему разделял хранилище со значением, которое " +"позже использовалось для проверок на коллизии. Предоставление этому значению" +" собственного времени жизни решило оставшееся перекрытие. После нескольких " +"целевых экспериментов {ph0}чистая перекомпиляция из исходного кода " +"подтвердила, что полная функция соответствует{ph1}." + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"Меня интересует, как открытие и испытания поддержали друг друга. Гипотеза о " +"времени жизни временных объектов дала агенту ИИ новое направление. Отзывы " +"компилятора помогли усовершенствовать эту гипотезу и привести ее в " +"соответствие с исходным кодом." + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "Другой граф потока управления" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"Вторая функция TH09 показывает, почему это новое направление может иметь " +"значение. Здесь препятствием было то, как несколько филиалов делились своей " +"итоговой работой. В более ранней работе {ph0}GPT-6.1-Sol{ph1} части функции " +"совпадали, но ветви по-прежнему соединялись иначе, чем в оригинале." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}GPT-6-Astra изменил окружающий граф потока управления{ph1}. Основные " +"пути теперь вели к общему финальному обновлению и возврату. В этой исходной " +"структуре компилятор объединил ветки так же, как в оригинале. Полная функция" +" совпала, и {ph2}отдельная проверка перестроения подтвердила это{ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}Изменение представления открыло более продуктивное пространство " +"поиска.{ph1} Оба случая дают мне повод серьезно отнестись к общим " +"возможностям модели: агент может долго пробовать локальные варианты, прежде " +"чем найти лучший способ выразить окружающую работу." + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"В то же время более поздние сеансы начинались с более раннего источника и " +"фиксировали сбои. Этот накопленный труд был частью их преимущества. История " +"позволяет нам проверять открытия и их проверки; контролируемое сравнение " +"поможет отделить эффект модели от унаследованного ею опыта." + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"Именно это делает вопрос для меня интересным. Некоторый прогресс был " +"достигнут благодаря поиску нового представительства. Большая часть " +"оставшейся работы заключалась в тестировании различных вариантов исходного " +"кода на знакомом компиляторе. Насколько это требует широких умственных " +"способностей? Насколько многому может научиться модель, неоднократно работая" +" с этим компилятором и кодом?" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "Почему специализированная модель ИИ может преуспеть?" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"Touhou дает нам конкретную причину ожидать, что этот опыт поможет. Большая " +"часть игрового кода принадлежит одному и тому же автору, ZUN, поэтому " +"повторяющиеся привычки — разумное исходное предположение. Репозитории " +"подтверждают это полезными примерами: связанные циклы и вспомогательные " +"механизмы служат источником гипотез для разных игр." + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "" +"Эти исходные шаблоны становятся более конкретными, когда мы подключаем " +"компилятор. В конкретной версии и наборе опций небольшие изменения в " +"исходном коде могут привести к повторяющимся различиям в машинном коде. " +"Некоторые из этих различий на удивление неясны." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"Например, в TH095 {ph0}даже имя локальной переменной может влиять на то, где" +" VC7.1 ее хранит{ph1}. Перемещение его декларации не решило проблему с " +"расположением хранилища. Однако более ранняя фоновая функция выявила шаблон " +"именования, который повлиял на выбор компилятора. Это предложило более " +"многообещающую гипотезу для {ph2}реконструкции {ph3}{ph4}." + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "" +"Повторное использование этого шаблона для переменной размера файла позволило" +" получить требуемый макет без увеличения объема памяти. Затем полная функция" +" совпала." + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "" +"Это очень специфическая деталь, о которой модель ИИ общего назначения может " +"не знать, когда впервые сталкивается с проблемой. Модель, специализированная" +" для этого компилятора, могла бы увидеть множество таких случаев и " +"определить, какие варианты исходного кода стоит протестировать в первую " +"очередь." + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"Эта возможность особенно очевидна в задачах окончательного сопоставления, " +"где мы уже понимаем поведение. Затем мы спрашиваем, какую обычную структуру " +"исходного кода этот компилятор превращает в наблюдаемые инструкции. " +"Специализация может помочь модели более эффективно предлагать эти формы, в " +"то время как цель по-прежнему определяет, какие гипотезы выживут." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"Полезные шаблоны должны сохранять свой контекст. TH08 использует более " +"раннюю версию Visual C++, чем TH095 и TH09. TH04 использует другой " +"компилятор эпохи DOS. Его {ph0}реконструкция кода игрока{ph1} требовала " +"различных гипотез о шаблонах исходного кода и о том, как скомпилированный " +"код связывается с исполняемым файлом. Наличие одного и того же автора дает " +"нам первоначальное ожидание, но каждая цель говорит нам, применимо ли оно. " +"Специализированная модель должна будет различать эти контексты." + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "Где следует хранить этот опыт?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"Прежде чем принять решение об обучении этим шаблонам посредством обучения " +"моделей, я бы посмотрел на знания, которые мы уже храним в репозитории. В " +"{ph0}предыдущем эссе{ph1} я писал о том, что оно стало рабочей памятью " +"проекта. Эта память включает в себя уроки компилятора, а также исходники и " +"неудачные эксперименты, которые сделали их полезными." + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"Получив эту запись, агент может начать с известного результата и проверить, " +"как мы его достигли. Это также позволяет избежать альтернатив, которые уже " +"потерпели неудачу в том же контексте. Начальная точка улучшается без " +"изменения обученных параметров модели." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"При реконструкции функции TH09 по созданию врагов сеанс {ph0}GPT-6-Luna-" +"max{ph1} взял гипотезу из соответствующего исходного кода TH08. Этот более " +"ранний код предлагал, как организовать цикл и обрабатывать сбои внутри него." +" Собственные доказательства TH09 предоставили подробности, касающиеся " +"конкретной игры. Перестройки из исходного кода подтвердили, что вся функция " +"совпадает." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}\"Модель не знала об этой особенности компилятора\" и \"модель не могла" +" ее использовать\" — это разные проблемы.{ph1} Извлечение может решить " +"первую, но превращение этого факта в полезного кандидата все равно требует " +"работы. И если исходный код-кандидат терпит неудачу, модель должна решить, " +"что означает результат для ее следующей попытки. Знание соответствующей " +"закономерности — это только начало этого процесса." + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"По этой причине я бы включил в любое сравнение меньшую модель ИИ общего " +"назначения с хорошей воспроизводимостью. Предоставление ему той же " +"библиотеки опыта поможет нам определить, что дает обучение: лучшее " +"генерирование кандидатов, лучшие решения после обратной связи или и то, и " +"другое." + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "Изучаем следующий полезный эксперимент" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"Эти решения после получения обратной связи — это то, что мне больше всего " +"хотелось бы изучить. При агентной реконструкции модель предлагает объяснение" +" и проверяет его на соответствие программе. Даже если исходный код-кандидат " +"дает сбой, результат может сузить оставшиеся возможности и предложить более " +"полезный следующий эксперимент." + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "" +"Снова рассмотрим пример временных результатов. Его окончательный источник " +"показывает сработавшую схему, но путь к этому источнику содержит больше " +"информации. Каждый из следующих экспериментов помог определить, что еще " +"необходимо изменить." + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "Эксперимент" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "Чему нас научил его результат" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "Попробуйте другой способ скопировать результаты" + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "Код копирования меняется, но функция по-прежнему отличается." + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "Используйте возвращаемые значения напрямую" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "" +"Копирование следует исходному шаблону, но временное хранилище все равно " +"отличается." + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "Сохраняйте все временные переменные действительными одновременно" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "" +"Они получают отдельное хранилище, но одно из них по-прежнему перекрывает " +"значение, используемое позже для проверок коллизий." + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "Держите значение проверки столкновений отдельно" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "" +"Чистая перекомпиляция из исходного кода подтверждает полное совпадение." + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "" +"Избранные эксперименты из приведенной выше реконструкции атакующей функции, " +"сгруппированные по тому, чему они нас научили." + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"Запись обучения, в которой сохраняется эта последовательность, может научить" +" большему, чем один только окончательный источник. Он связывает каждое " +"предлагаемое изменение с наблюдаемым результатом и следующим решением. " +"Сохранение неэффективных вариантов также имеет значение: они сообщают " +"следующему агенту, какие гипотезы уже были проверены в этом контексте." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}Я бы хотел, чтобы модель научилась использовать обратную связь.{ph1} " +"Нейтральный результат — повод пересмотреть вариант; измененное " +"несоответствие может указывать на другую причину. Когда локальные изменения " +"перестают быть информативными, агент должен иметь возможность вернуться к " +"исходному представлению или снова проверить доказательства." + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"Чтобы научиться делать такой выбор, требуется автономия. Иногда полезным " +"следующим шагом является проверка другого вызывающего объекта, а не " +"компиляция еще одного редактирования. Жесткая последовательность необходимых" +" переписываний устранит этот выбор вместе с частью поведения, которому мы " +"хотим, чтобы модель научилась." + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "Чем реверс-инжиниринг интересен для обучения с подкреплением" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"Реконструкция с заданными границами даёт практическую среду для изучения " +"этих решений. Когда версии цели и компилятора зафиксированы, многие " +"эксперименты с исходным кодом дают быструю, воспроизводимую обратную связь. " +"Агент может скомпилировать кандидат, изучить различия и выбрать следующий " +"шаг." + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"Обучение с подкреплением могло бы тренировать этот процесс принятия решений " +"посредством получаемой обратной связи. Кандидат, принятый посредством " +"определенной проверки, дает нам конкретный результат, а последовательность " +"попыток позволяет нам наблюдать, сколько работы потребовалось для его " +"достижения." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"Уже есть исследования, подтверждающие это направление. " +"{ph0}LLM4Decompile{ph1} изучает модели, предназначенные для декомпиляции. " +"{ph2}AutoDecompiler{ph3} обучает многоэтапному уточнению с использованием " +"компилятора и обратной связи при выполнении. Их исследования сосредоточены " +"на функциональном восстановлении. В этой работе я бы использовал их в " +"качестве отправной точки для решения соответствующей задачи по поиску " +"источника, соответствующего выводам исторического компилятора." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"Однако для решения такой четко определенной задачи нам, возможно, сначала " +"придется установить, какими ресурсами владеет функция, или разработать новый" +" способ наблюдения за поведением программы во время выполнения. Например, в " +"TH08 {ph0}разность коллизий привела к тому, как исходная программа " +"обрабатывала вычисления с плавающей запятой{ph1}. Прежде чем агент смог " +"протестировать полезную поправку, он должен был решить, что именно измерять." + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "" +"Это предполагает еще одну роль модели с широкими возможностями: в первую " +"очередь помочь сделать проблему проверяемой. Как только эта проверка " +"появится, мы сможем выяснить, насколько далеко может зайти изученная " +"политика поиска." + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "Когда программа проверки ошибается" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"Когда проверка используется для обучения, её охват становится частью среды " +"обучения. Я называю такой эталон или проверяющий инструмент оракулом. Даже " +"воспроизводимый ответ нужно понимать в пределах того, что он действительно " +"проверяет." + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"TH08 показал, как много может скрываться за пределами этого покрытия. " +"Некоторые реконструированные функции прошли точное сравнение с неправильными" +" плавающими константами. Компаратор корректировал перемещенные адреса перед " +"проверкой инструкций, но проверял значения, стоящие за этими адресами, " +"только тогда, когда они были явно записаны для проверки. Другие буквальные " +"ссылки могут пройти без проверки их значений." + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"Чтобы устранить этот пробел, {ph0}более широкий аудит{ph1} обнаружил " +"неправильные константы в функциях, которые уже прошли проверку. В одном " +"расчете в реконструированный исходный код добавлен {ph2}, тогда как в " +"исходный добавлен {ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}Модель, получившая награду в результате старой проверки, могла " +"научиться производить неверную реконструкцию.{ph1} Мы не обучали модель RL с" +" помощью этой проверки. Сбой, который мы наблюдали, заключался в самой " +"проверке. Но если бы мы использовали это в качестве награды, то же самое " +"слепое пятно стало бы частью среды обучения." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"Функциональный тест может иметь аналогичное «слепое пятно». " +"{ph0}Исследование с использованием дифференциального фаззинга в " +"декомпиляторах LLM{ph1} выявило различия в поведении за пределами " +"предоставленных тестов. Поэтому нам необходимо понимать прохождение теста с " +"точки зрения случаев, в которых он проводится. Точно так же совпадение " +"инструкций следует понимать с точки зрения байтов и данных, которые оно " +"проверяет." + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"Прежде чем использовать какой-либо вид проверки в качестве награды, я бы " +"протестировал ее с заведомо неверными результатами. Я также хотел бы хранить" +" окончательное принятие отдельно от исходного кода, который может " +"редактировать агент ИИ. Модель должна пройти проверку путем правильного " +"восстановления программы. В противном случае простое копирование массива " +"байтов из целевого объекта может обмануть наивную систему оценки без " +"восстановления полезного исходного кода." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "" +"{ph0}Улучшение модели и улучшение её проверяющего инструмента — части одной " +"исследовательской задачи.{ph1} Чем лучше модель оптимизирует получаемую " +"обратную связь, тем важнее понимать саму эту связь." + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "Сравнение, которое стоит провести" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"Имея эти проверки, я бы начал сравнение с фиксированного семейства задач " +"VC7.1. Во-первых, я бы установил базовые показатели для сильной модели ИИ " +"общего назначения и для более мелкой модели. Добавление знаний о репозитории" +" в меньшую модель покажет, какие изменения происходят в извлечении. Отсюда " +"контролируемая специализация и версия, обученная RL, позволят нам изучить, " +"что добавляет обучение." + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"Чтобы сделать эти сравнения информативными, каждая модель должна получить " +"одни и те же целевые доказательства и инструменты. Для сравнений по " +"конкретному обучению я бы также оставил фиксированной базовую модель и " +"доступные знания. Повторные испытания помогут отличить надежную стратегию " +"поиска от возможного решения, которое окажется успешным случайно." + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"Затем я бы разделил два начальных условия: восстановление функции из ее " +"инструкций и закрытие последних нескольких различий в поддерживаемом " +"исходном коде. Специализированная модель ИИ может превосходно справиться со " +"второй задачей, в то время как модель ИИ общего назначения выполняет большую" +" часть работы, необходимой для ее достижения. Измерение их по отдельности " +"выявило бы такое разделение работы." + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"Обе задачи требуют тестовых примеров, исключенных из обучения и поиска. " +"Связанные игры Touhou имеют общий код движка. Исключение одной игры из " +"обучения может привести к тому, что в обучающем наборе останутся почти " +"идентичные функции. Вместо этого я бы исключил целые группы связанного " +"исходного кода и исключил бы их проверенные ответы как из обучающих данных, " +"так и из библиотеки поиска." + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"В этих примерах результатом будут полные, независимо проверенные совпадения." +" Равные бюджеты для предложений-кандидатов или попыток компиляции помогут " +"сравнить качество поиска. Измерение общего времени и затрат, включая " +"компиляцию, покажет, обеспечивает ли это качество эффективный рабочий " +"процесс. Затраты на обучение следует оценивать отдельно." + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"Оба измерения имеют значение. Дешевое предложение может привести к " +"дорогостоящему рабочему процессу, если оно приведет к увеличению количества " +"компиляций, не содержащих полезной информации. И наоборот, более медленная " +"модель может быть более экономичной, если она быстрее обнаружит полезный " +"эксперимент. Сравнение должно включать эти затраты." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"Подсчет принятых результатов также позволяет учитывать промежуточный " +"прогресс. Один TH09 {ph0}кандидат на воспроизведение-сохранение{ph1} " +"выглядел многообещающе, поскольку скомпилированная функция имела ожидаемый " +"размер, но полное сравнение все же выявило существенные различия. Изменения " +"в том, как компилятор организует инструкции, также могут создать " +"впечатление, что кандидат ближе к цели, не решая при этом основную проблему." +" Такая диагностика может помочь в следующем эксперименте, но я бы сопоставил" +" любую награду за «приближение» с полной приемочной проверкой." + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"Меня бы заинтересовала закономерность этих результатов. Если " +"специализированная модель ИИ хорошо работает в знакомом семействе " +"компиляторов, сохранится ли это преимущество при изменении инструментальной " +"цепочки? И как только обе модели ИИ будут хорошо воспроизводиться, сколько " +"еще добавится обучение? Ответы помогут нам решить, где тот или иной тип " +"модели наиболее полезен." + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "О каком ИИ-агенте идет речь?" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"Если модели окажутся полезными на разных этапах, полезным механизмом может " +"стать широкий агент с доступом к специализированной модели ИИ. Как только " +"задача становится привычным поиском компилятора, он может запросить " +"кандидатов у специализированной модели ИИ. Если результаты перестанут иметь " +"смысл, более широкий агент может вернуться к целевым данным или исследовать " +"само измерение." + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "" +"В таком случае специализация становится инструментом, который агент может " +"выбирать по мере развития расследования. Агент сохраняет свободу менять " +"направление, которое сделало возможными предыдущие прорывы." + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"Это естественным образом следует из промышленного сдвига, который я описал в" +" предыдущем эссе. Возможность проводить больше экспериментов меняет то, как " +"мы организуем работу. Это также дает нам повод задаться вопросом, какие " +"решения требуют широкого суждения, а какие улучшаются за счет повторного " +"опыта работы с конкретным ремеслом." + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"Пока самая сильная универсальная модель заслужила место в моём рабочем " +"процессе, решив проблемы, которые прежде оставались нерешёнными. Эти успехи " +"побуждают меня изучить процесс внимательнее: какая часть зависела от широты " +"её возможностей, а какую могла бы выполнить модель, обученная именно такой " +"реконструкции?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "" +"{ph0}Репозитории дают нам возможность проверить вопрос.{ph1} Я хотел бы " +"использовать эту запись для сравнения и посмотреть, что мы узнаем." + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "Доказательства и атрибуция моделей" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"В примерах описаны исторические сравнения на уровне функций, записанные в " +"связанных коммитах. Проверки во время выполнения всей игры — это отдельные " +"этапы. Источник и соответствующие записи были проверены 13 октября 2026 " +"года." + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"Метка TH09 {ph0} означает GPT-6-Astra. Модель, связанная с {ph1}, со " +"временем изменилась, поэтому сама по себе метка не может идентифицировать " +"модель, использованную в конкретном прогоне. Явные названия моделей в других" +" цитируемых коммитах обеспечивают записанную атрибуцию. Эти истории не " +"включают в себя последовательные измерения затрат или усилий для каждого " +"запуска." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "" +"{ph0}TH09 время жизни временных объектов:{ph1} {ph2}предыдущая проверка " +"контекста{ph3} и {ph4}полная реконструкция, подтвержденная чистой " +"перекомпиляцией из исходного кода{ph5}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"Обратный вызов {ph0}TH09 Front:{ph1} {ph2}диагностические области, которые " +"не соответствуют{ph3}, {ph4}Astra новому графу потока управления{ph5} и его " +"{ph6}принятой проверке перекомпиляции{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}Знание компилятора:{ph1} {ph2}TH095 повторное использование поведения " +"сегмента идентификаторов{ph3}, {ph4}TH04 исходный код игрока и порядок " +"компоновщика{ph5} и полная реконструкция {ph6}Luna функции создания врагов " +"TH09{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}Проверки и диагностика:{ph1} {ph2}TH08 аудит констант с плавающей " +"запятой{ph3}, {ph4}TH08 численное исследование{ph5} и {ph6}TH09 " +"реконструкция с сохранением повторов{ph7}." + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "" +"Предлагаемые сравнения специализированных моделей и обучение RL — это " +"будущие эксперименты. Их мотивирует история проектов. Для этого эссе не " +"оценивалась обученная специализированная модель." + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "Нужна ли реверс-инжинирингу модель большего размера? | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "" +"Чему реконструкция Touhou научила меня об общих моделях, специализированных " +"моделях и умении предлагать лучшие гипотезы на основе отзывов компилятора." + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "На этой странице" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "Эссе «Модели и реверс-инжиниринг»" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "Избранные эксперименты по реконструкции" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "Наверх" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "" +"{ph0}Подробные записи о доказательствах{ph1} содержат результаты сравнений и" +" контекст экспериментов." + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "Автор: N0zoM1z0 · 13 октября 2026 г. · Черновик для обсуждения" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "Руководство по установке" diff --git a/website/locales/th/messages.po b/website/locales/th/messages.po index 94e6d1873..45c67209b 100644 --- a/website/locales/th/messages.po +++ b/website/locales/th/messages.po @@ -32,18 +32,18 @@ msgid "Thoughts on reverse engineering." msgstr "ความคิดเกี่ยวกับวิศวกรรมย้อนกลับ" #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "ฟื้นฟูเกม{ph0}เรียงความ" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "การปฏิวัติอุตสาหกรรมในวิศวกรรมย้อนกลับ" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " @@ -52,19 +52,20 @@ msgstr "" "สิ่งที่คู่มือใหม่และ " "reconstructingTH08,TH095และTH04สอนฉันเกี่ยวกับเจ้าหน้าที่ปลายทางและความรู้นั่นรประกอบที่อีกฝั่งยิ่งสนง.โครงการ." -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "อ่านบทความ" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "โดย N0zoM1z0 ·10 ตุลาคม 2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -100,6 +101,8 @@ msgstr "" "และเจ้าหน้าที่ปัญญาประดิษฐ์" #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -135,6 +138,7 @@ msgstr "" "REA-หาวิธีการทำงานของซอฟต์แวร์ วิศวกรรมย้อนกลับกับตัวแทนการเขียนโค้ดของคุณ" #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -155,6 +159,7 @@ msgid "REA home" msgstr "หน้าแรก REA" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -175,6 +180,7 @@ msgid "Main navigation" msgstr "เมนูหลัก" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -195,6 +201,7 @@ msgid "REA on GitHub" msgstr "REA บน GitHub" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -215,6 +222,7 @@ msgid "Join REA on Discord" msgstr "เข้าร่วม REA บน Discord" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -234,7 +242,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "ติดตาม REA บน X" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "กลับขึ้นด้านบน" @@ -11376,6 +11384,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "ระยะห่างเดียวกัน:256÷16=16 หน่วยมุม=22.5°" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -11396,6 +11405,7 @@ msgid "Showcases" msgstr "ตัวอย่าง" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -11416,6 +11426,7 @@ msgid "Blog" msgstr "บล็อก" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -11436,6 +11447,7 @@ msgid "Get started" msgstr "เริ่มต้น" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -11455,7 +11467,8 @@ msgctxt "shared" msgid "Guides" msgstr "คู่มือ" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -11475,7 +11488,8 @@ msgctxt "shared" msgid "Source" msgstr "ซอร์สโค้ด" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -11495,7 +11509,8 @@ msgctxt "shared" msgid "MIT license" msgstr "สัญญาอนุญาต MIT" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -11515,7 +11530,8 @@ msgctxt "shared" msgid "Join the community" msgstr "เข้าร่วมชุมชน" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -12477,6 +12493,1356 @@ msgstr "" "หรือเชื่อมต่อเซิร์ฟเวอร์ MCP ของ Everywhere " "เพื่อตรวจสอบทราฟฟิกที่บันทึกไว้ร่วมกับเอเจนต์ของคุณ" +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "โมเดลเฉพาะทาง{ph0}บทความ" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "การวิศวกรรมย้อนกลับจำเป็นต้องใช้โมเดลที่ใหญ่ขึ้นไหม?" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "" +"ข้อคิดจากการสร้าง Touhou ขึ้นใหม่ เกี่ยวกับโมเดลทั่วไป โมเดลเฉพาะทาง " +"และการเรียนรู้จากผลตอบกลับของคอมไพเลอร์" + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "โดย N0zoM1z0 · 13 ตุลาคม 2026" + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "ข้ามไปที่เนื้อหา" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "{ph0}Home{ph1} / {ph2}Blog{ph3} / โมเดลและวิศวกรรมย้อนกลับ" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "เรียงความ" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "วิศวกรรมย้อนกลับจำเป็นต้องมีโมเดลที่ใหญ่กว่านี้หรือไม่?" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "โดย N0zoM1z0 · 13 ตุลาคม 2026" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "ประเด็นสำคัญ" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "" +"{ph0}ความสามารถของโมเดลส่งผลต่อสมมติฐานที่เอเจนต์ AI สามารถเสนอได้{ph1} " +"เซสชันต่อมาได้แก้ไขปัญหาที่งานก่อนหน้านี้ยังไม่ได้รับการแก้ไข" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "" +"{ph0}คอมไพเลอร์ที่คุ้นเคยนำเสนอรูปแบบที่เป็นรูปธรรมสำหรับโมเดลเฉพาะทางในการเรียนรู้{ph1}" +" " +"การจับคู่โค้ดเครื่องที่แน่นอนบางรายการขึ้นอยู่กับรูปแบบซอร์สโค้ดเฉพาะที่สามารถนำมาใช้ซ้ำได้" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "" +"{ph0}รวมความรู้ของพื้นที่เก็บข้อมูลไว้ในการเปรียบเทียบที่ยุติธรรม{ph1} " +"โมเดลขนาดเล็กที่มีการดึงความรู้ที่ดีอาจมีข้อมูลเพียงพอที่จะดำเนินการต่อไป" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "" +"{ph0}ฝึกแบบจำลองเพื่อเลือกการทดลองที่มีประโยชน์ถัดไป " +"และทดสอบเครื่องมือตรวจสอบการยืนยัน{ph1} " +"ความคิดเห็นจะมีประโยชน์เฉพาะในขอบเขตที่ผู้ตรวจสอบตรวจสอบสิ่งที่ถูกต้องเท่านั้น" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "" +"{ph0}ประเมินผลการฟื้นฟูที่ได้รับการยืนยันควบคู่ไปกับเวลาและต้นทุน{ph1} " +"นั่นคือสิ่งที่ฉันต้องการวัดสำหรับเวิร์กโฟลว์เอเจนต์ AI ที่สมบูรณ์" + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "ในบทความนี้" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}โมเดลที่เก่งขึ้นเปลี่ยนอะไรบ้าง?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}ทำไมจึงมีความเชี่ยวชาญ?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}ประสบการณ์นี้ควรเก็บไว้ที่ไหน?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}เรียนรู้การทดลองที่มีประโยชน์ครั้งต่อไป{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}วิศวกรรมย้อนกลับและการเสริมกำลัง{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}เมื่อตัวตรวจสอบความถูกต้องผิดพลาด{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}การเปรียบเทียบที่คุ้มค่า{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}สิ่งนี้แนะนำเอเจนต์ AI ประเภทใด{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "โมเดลที่เก่งขึ้นเปลี่ยนอะไรบ้าง?" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"ตั้งแต่เดือนสิงหาคม 2026 " +"ฉันได้สำรวจว่าตัวแทนสามารถดำเนินการวิศวกรรมย้อนกลับได้มากเพียงใดโดยมีสิทธิ์เข้าถึงโปรแกรมและวิธีการตรวจสอบงาน" +" ประสบการณ์ส่วนใหญ่ของฉันมาจากการสร้างเกมขึ้นใหม่ โดยเฉพาะ Touhou " +"ขณะที่ฉันเปลี่ยนโมเดล " +"พื้นที่เก็บข้อมูลได้เก็บบันทึกว่าแต่ละเซสชันจัดการเพื่อกู้คืนอะไรบ้าง" + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"งานส่วนใหญ่มีเป้าหมายให้ซอร์สโค้ดที่สร้างขึ้นคอมไพล์แล้วตรงกับต้นฉบับ " +"เราใช้ชุดเครื่องมือจากยุคนั้นโดยกำหนดเวอร์ชันไว้แน่นอน " +"แล้วตรวจว่าผลลัพธ์ตรงกับฟังก์ชันเป้าหมายหรือไม่ " +"เมื่อโมเดลรุ่นใหม่แก้จุดที่งานก่อนหน้าติดอยู่ได้ " +"การเปลี่ยนแปลงซอร์สโค้ดช่วยให้เห็นว่าอะไรทำให้ก้าวหน้าได้" + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "ตัวแปรชั่วคราวจำเป็นต้องมีอายุการใช้งานที่ทับซ้อนกัน" + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"ลอจิกของฟังก์ชันการโจมตี TH09 ส่วนใหญ่ได้ถูกสร้างขึ้นใหม่แล้ว " +"แต่คอมไพเลอร์ยังคงเก็บผลลัพธ์ชั่วคราวแตกต่างไปจากต้นฉบับ " +"ปัญหาที่เหลืออยู่คือผลลัพธ์เหล่านั้นต้องใช้เวลานานเท่าใดจึงจะคงอยู่ได้ " +"และเมื่อใดจึงจะสามารถนำพื้นที่จัดเก็บกลับมาใช้ใหม่ได้" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"บันทึกเซสชัน {ph0}GPT-6-Sol{ph1} " +"รายงานความไม่ตรงกันนี้หลังจากทดสอบการจัดเตรียมซอร์สโค้ดทั่วไปหลายรายการ " +"เมื่อ {ph2}GPT-6.1-Sol ตรวจสอบปัญหาอีกครั้ง{ph3} " +"ก็เสนอสมมติฐานที่เป็นประโยชน์เกี่ยวกับช่วงอายุของตัวแปรชั่วคราวเหล่านี้" + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"ฟังก์ชันนี้สร้างผลลัพธ์ชั่วคราวและคัดลอกไปยังตำแหน่งแอนิเมชัน ในภาษา C++ " +"ผลลัพธ์ชั่วคราวจะคงอยู่จนกว่านิพจน์ที่ใช้จะเสร็จสิ้น " +"การจัดกลุ่มการดำเนินการจริงให้เป็นนิพจน์เดียวทำให้ผลลัพธ์เหล่านั้นคงอยู่ร่วมกัน" +" " +"ดังนั้นคอมไพลเลอร์จึงไม่สามารถใช้พื้นที่เก็บข้อมูลเดียวกันซ้ำได้อีกต่อไปสำหรับการดำเนินการทั้งหมด" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"ผลลัพธ์หนึ่งรายการยังคงแชร์พื้นที่เก็บข้อมูลด้วยค่าที่ใช้ในภายหลังสำหรับการตรวจสอบการชนกัน" +" การให้คุณค่านั้นตลอดอายุการใช้งานจะช่วยแก้ไขการทับซ้อนที่เหลือ " +"หลังจากการทดลองที่กำหนดเป้าหมายหลายครั้ง " +"{ph0}การคอมไพล์ใหม่ทั้งหมดจากแหล่งที่มายืนยันว่าฟังก์ชันทั้งหมดตรงกัน{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"ฉันสนใจว่าการค้นพบและการทดสอบสนับสนุนซึ่งกันและกันอย่างไร " +"สมมติฐานเกี่ยวกับอายุการใช้งานของวัตถุชั่วคราวทำให้เอเจนต์ AI มีทิศทางใหม่ " +"คำติชมของคอมไพเลอร์ช่วยปรับแต่งสมมติฐานนั้นให้กลายเป็นการจัดเรียงซอร์สโค้ดที่ตรงกัน" + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "กราฟโฟลว์ควบคุมที่แตกต่างกัน" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"ฟังก์ชัน TH09 ตัวที่สองแสดงให้เห็นว่าเหตุใดทิศทางใหม่จึงมีความสำคัญ " +"อุปสรรคอยู่ที่ว่าหลายสาขาจะแบ่งปันผลงานชิ้นสุดท้ายของพวกเขาอย่างไร " +"งานก่อนหน้าของ {ph0}GPT-6.1-Sol{ph1} มีฟังก์ชันบางส่วนที่เข้ากัน " +"แต่กิ่งก้านยังคงเชื่อมกันแตกต่างไปจากต้นฉบับ" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}GPT-6-Astra เปลี่ยนกราฟโฟลว์ควบคุมโดยรอบ{ph1} " +"เส้นทางหลักตอนนี้นำไปสู่การอัปเดตและการกลับมาครั้งสุดท้ายที่ใช้ร่วมกัน " +"ในโครงสร้างต้นทางนั้น คอมไพลเลอร์จะรวมสาขาต่างๆ ในลักษณะเดียวกับต้นฉบับ " +"ฟังก์ชันที่สมบูรณ์ตรงกัน และ " +"{ph2}การตรวจสอบการสร้างใหม่แยกกันยืนยันแล้ว{ph3}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}การเปลี่ยนการแสดงทำให้พื้นที่การค้นหามีประสิทธิผลมากขึ้น{ph1} " +"ทั้งสองกรณีให้เหตุผลแก่ฉันในการให้ความสำคัญกับความสามารถของโมเดลทั่วไปอย่างจริงจัง:" +" " +"ตัวแทนสามารถลองใช้รูปแบบท้องถิ่นต่อไปเป็นเวลานานก่อนที่จะพบวิธีที่ดีกว่าในการแสดงงานโดยรอบ" + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"ในเวลาเดียวกัน " +"เซสชันต่อมาเริ่มต้นด้วยแหล่งที่มาก่อนหน้าและความล้มเหลวที่บันทึกไว้ " +"งานที่สะสมไว้นั้นเป็นส่วนหนึ่งของความได้เปรียบของพวกเขา " +"ประวัติศาสตร์ช่วยให้เราตรวจสอบการค้นพบและการตรวจสอบของพวกเขา " +"การเปรียบเทียบแบบควบคุมจะช่วยแยกผลกระทบของแบบจำลองออกจากประสบการณ์ที่สืบทอดมา" + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"นี่คือสิ่งที่ทำให้คำถามน่าสนใจสำหรับฉัน " +"ความคืบหน้าบางอย่างมาจากการค้นหาตัวแทนใหม่ " +"งานที่เหลือส่วนใหญ่เกี่ยวข้องกับการทดสอบการจัดเตรียมซอร์สโค้ดที่แตกต่างกันกับคอมไพเลอร์ที่คุ้นเคย" +" สิ่งนี้ต้องใช้ความสามารถในการให้เหตุผลแบบกว้างๆ มากน้อยเพียงใด? " +"โมเดลสามารถเรียนรู้ได้มากเพียงใดจากการทำงานซ้ำๆ กับคอมไพเลอร์และโค้ดนั้น" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "เหตุใดโมเดล AI เฉพาะทางจึงทำได้ดี" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"Touhou ให้เหตุผลที่ชัดเจนแก่เราในการคาดหวังว่าประสบการณ์นั้นจะช่วยได้ " +"รหัสเกมส่วนใหญ่มาจากผู้เขียนคนเดียวกัน ZUN ดังนั้นนิสัยที่เกิดขึ้นซ้ำๆ " +"จึงเป็นสมมติฐานเริ่มต้นที่สมเหตุสมผล " +"แหล่งเก็บข้อมูลสนับสนุนด้วยตัวอย่างที่เป็นประโยชน์: " +"ลูปที่เกี่ยวข้องและการจัดเตรียมตัวช่วยได้ให้สมมติฐานแก่เกมต่างๆ" + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "" +"รูปแบบแหล่งที่มาเหล่านั้นมีความเฉพาะเจาะจงมากขึ้นเมื่อเรารวมคอมไพเลอร์ " +"ภายใต้เวอร์ชันและชุดตัวเลือกเฉพาะ การเปลี่ยนแปลงเล็กๆ น้อยๆ " +"ในแหล่งที่มาอาจทำให้เกิดความแตกต่างที่ทำซ้ำได้ในรหัสเครื่อง " +"ความแตกต่างบางประการนั้นคลุมเครืออย่างน่าประหลาดใจ" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"ตัวอย่างเช่น ใน TH095 {ph0}แม้แต่ชื่อของตัวแปรโลคัลก็อาจส่งผลต่อตำแหน่งที่ " +"VC7.1 เก็บไว้{ph1} การย้ายการประกาศไม่ได้ช่วยแก้ปัญหารูปแบบการจัดเก็บข้อมูล " +"อย่างไรก็ตาม " +"ฟังก์ชันพื้นหลังก่อนหน้านี้ได้เปิดเผยรูปแบบการตั้งชื่อที่ส่งผลต่อการเลือกของคอมไพเลอร์" +" นั่นเสนอสมมติฐานที่มีแนวโน้มมากขึ้นสำหรับ {ph2}การสร้าง {ph3}{ph4} ใหม่" + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "" +"การใช้รูปแบบนั้นซ้ำสำหรับตัวแปรขนาดไฟล์ทำให้เกิดเค้าโครงที่ต้องการโดยไม่ต้องเพิ่มพื้นที่เก็บข้อมูล" +" ฟังก์ชั่นครบถ้วนจึงเข้าคู่กัน" + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "" +"นี่เป็นรายละเอียดเฉพาะเจาะจงมากที่โมเดล AI " +"เอนกประสงค์อาจไม่ทราบเมื่อพบปัญหาครั้งแรก " +"โมเดลเฉพาะสำหรับคอมไพลเลอร์นี้สามารถเห็นกรณีดังกล่าวได้มากมาย " +"และเรียนรู้ว่าซอร์สโค้ดรูปแบบใดที่ควรค่าแก่การทดสอบก่อน" + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"โอกาสมีความชัดเจนโดยเฉพาะอย่างยิ่งในปัญหาการจับคู่ขั้นสุดท้ายที่เราเข้าใจพฤติกรรมอยู่แล้ว" +" " +"จากนั้นเราจะถามว่าการจัดเรียงซอร์สโค้ดธรรมดาใดที่คอมไพเลอร์นี้เปลี่ยนเป็นคำสั่งที่สังเกตได้" +" " +"ความเชี่ยวชาญพิเศษสามารถช่วยแบบจำลองเสนอรูปแบบเหล่านั้นได้อย่างมีประสิทธิภาพมากขึ้น" +" ในขณะที่เป้าหมายยังคงกำหนดว่าสมมติฐานใดที่จะอยู่รอดได้" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"รูปแบบที่ใช้ได้ต้องมีบริบทกำกับ TH08 ใช้ Visual C++ รุ่นเก่ากว่า TH095 และ " +"TH09 ส่วน TH04 ใช้คอมไพเลอร์อีกตัวหนึ่งจากยุค DOS " +"{ph0}การสร้างโค้ดผู้เล่นขึ้นใหม่{ph1} จึงต้องใช้สมมติฐานต่างออกไป " +"ทั้งเรื่องรูปแบบซอร์สโค้ดและการลิงก์เป็นไฟล์ปฏิบัติการ " +"ผู้เขียนคนเดียวกันให้ข้อสันนิษฐานเริ่มต้น " +"แต่ต้องตรวจในแต่ละเป้าหมายว่าใช้ได้หรือไม่ " +"โมเดลเฉพาะทางต้องเรียนรู้ความแตกต่างเหล่านี้" + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "ประสบการณ์นี้ควรเก็บไว้ที่ไหน?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"ก่อนที่จะตัดสินใจสอนรูปแบบเหล่านั้นผ่านการฝึกโมเดล " +"ฉันจะดูความรู้ที่เราเก็บไว้ในที่เก็บอยู่แล้ว ใน {ph0}เรียงความก่อนหน้า{ph1} " +"ฉันเขียนเกี่ยวกับการที่กลายเป็นความทรงจำในการทำงานของโครงการ " +"หน่วยความจำดังกล่าวประกอบด้วยบทเรียนเกี่ยวกับคอมไพเลอร์ " +"พร้อมด้วยแหล่งที่มาและการทดลองที่ล้มเหลวซึ่งทำให้มีประโยชน์" + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"ด้วยการเรียกบันทึกนั้น " +"ตัวแทนสามารถเริ่มต้นด้วยผลลัพธ์ที่ทราบและตรวจสอบว่าเราเข้าถึงได้อย่างไร " +"นอกจากนี้ยังสามารถหลีกเลี่ยงทางเลือกอื่นที่ล้มเหลวในบริบทเดียวกันได้ " +"จุดเริ่มต้นจะดีขึ้นโดยไม่ต้องเปลี่ยนพารามิเตอร์ที่ได้รับการฝึกของโมเดล" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"ในขณะที่สร้างฟังก์ชันของ TH09 ขึ้นมาใหม่เพื่อสร้างศัตรู เซสชัน " +"{ph0}GPT-6-Luna-max{ph1} ได้ตั้งสมมุติฐานจากซอร์สโค้ด TH08 ที่เกี่ยวข้อง " +"โค้ดก่อนหน้านี้แนะนำวิธีจัดระเบียบลูปและจัดการกับความล้มเหลวภายใน หลักฐานของ" +" TH09 ให้รายละเอียดเฉพาะเกม " +"การสร้างใหม่จากแหล่งที่มายืนยันว่าฟังก์ชันทั้งหมดตรงกัน" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}\"โมเดลไม่ทราบว่านิสัยแปลกๆ ของคอมไพเลอร์\" และ " +"\"โมเดลไม่สามารถใช้งานได้\" เป็นปัญหาที่แตกต่างกัน {ph1} " +"การดึงข้อมูลอาจแก้ปัญหาได้ในวิธีแรก " +"แต่การเปลี่ยนข้อเท็จจริงดังกล่าวให้กลายเป็นตัวเลือกที่มีประโยชน์ยังคงต้องใช้เวลา" +" และหากซอร์สโค้ดของผู้สมัครล้มเหลว " +"โมเดลจะต้องตัดสินใจว่าผลลัพธ์มีความหมายอย่างไรสำหรับความพยายามครั้งถัดไป " +"การรู้รูปแบบที่เกี่ยวข้องเป็นเพียงจุดเริ่มต้นของกระบวนการนั้นเท่านั้น" + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"ด้วยเหตุผลดังกล่าว ฉันจึงรวมโมเดล AI " +"อเนกประสงค์ที่มีขนาดเล็กกว่าพร้อมการดึงข้อมูลที่ดีไว้ด้วยในการเปรียบเทียบ " +"การให้คลังประสบการณ์แบบเดียวกันจะช่วยให้เราระบุได้ว่าการฝึกอบรมใดที่เพิ่มเข้ามา" +" เช่น การสร้างผู้สมัครที่ดีขึ้น การตัดสินใจที่ดีขึ้นหลังจากได้รับคำติชม " +"หรือทั้งสองอย่าง" + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "เรียนรู้การทดลองที่มีประโยชน์ครั้งต่อไป" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"การตัดสินใจเหล่านั้นหลังจากได้รับคำติชมคือสิ่งที่ฉันอยากศึกษามากที่สุด " +"ในการฟื้นฟูแบบเอเจนต์ แบบจำลองจะเสนอคำอธิบายและทดสอบกับโปรแกรม " +"แม้ว่าซอร์สโค้ดของผู้สมัครจะล้มเหลว " +"ผลลัพธ์ก็สามารถจำกัดความเป็นไปได้ที่เหลืออยู่ให้แคบลง " +"และแนะนำการทดลองถัดไปที่มีประโยชน์มากขึ้น" + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "" +"ลองพิจารณาตัวอย่างผลลัพธ์ชั่วคราวอีกครั้ง " +"แหล่งที่มาสุดท้ายแสดงการจัดเตรียมที่ได้ผล " +"แต่เส้นทางไปยังแหล่งข้อมูลนั้นมีข้อมูลเพิ่มเติม " +"การทดลองแต่ละรายการต่อไปนี้ช่วยระบุสิ่งที่ยังจำเป็นต้องเปลี่ยนแปลง" + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "การทดลอง" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "ผลลัพธ์ของมันสอนอะไรเรา" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "ลองวิธีอื่นในการคัดลอกผลลัพธ์" + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "รหัสการคัดลอกเปลี่ยนไป แต่ฟังก์ชันยังคงแตกต่างออกไป" + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "ใช้ค่าที่ส่งคืนโดยตรง" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "" +"การคัดลอกเป็นไปตามรูปแบบดั้งเดิม แต่การจัดเก็บชั่วคราวยังคงแตกต่างออกไป" + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "เก็บตัวแปรชั่วคราวทั้งหมดให้ถูกต้องในเวลาเดียวกัน" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "" +"พวกเขาได้รับพื้นที่เก็บข้อมูลแยกต่างหาก " +"แต่ยังมีอีกหนึ่งค่าที่ทับซ้อนกันกับค่าที่ใช้ในภายหลังสำหรับการตรวจสอบการชนกัน" + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "แยกค่าการตรวจสอบการชนกันออกจากกัน" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "การคอมไพล์ใหม่ทั้งหมดจากแหล่งที่มายืนยันการจับคู่ที่สมบูรณ์" + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "" +"การทดลองที่เลือกจากการสร้างฟังก์ชันการโจมตีขึ้นใหม่ด้านบน " +"โดยจัดกลุ่มตามสิ่งที่พวกเขาสอนเรา" + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"บันทึกการฝึกอบรมที่เก็บลำดับนี้สามารถสอนได้มากกว่าแหล่งข้อมูลสุดท้ายเพียงอย่างเดียว" +" " +"โดยเชื่อมโยงการเปลี่ยนแปลงที่เสนอแต่ละรายการกับผลลัพธ์ที่สังเกตได้และการตัดสินใจครั้งต่อไป" +" การรักษารูปแบบที่ไม่มีประสิทธิภาพก็มีความสำคัญเช่นกัน " +"โดยจะแจ้งตัวแทนในภายหลังว่าสมมติฐานใดได้รับการทดสอบแล้วในบริบทนั้น" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}ฉันอยากให้โมเดลเรียนรู้วิธีใช้คำติชม{ph1} " +"ผลลัพธ์ที่เป็นกลางคือเหตุผลที่ต้องพิจารณารูปแบบใหม่อีกครั้ง " +"ความไม่ตรงกันที่เปลี่ยนแปลงอาจชี้ไปที่สาเหตุอื่น " +"เมื่อการแก้ไขเฉพาะที่หยุดให้ข้อมูล " +"ตัวแทนควรสามารถทบทวนการนำเสนอแหล่งที่มาหรือตรวจสอบหลักฐานอีกครั้ง" + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"การเรียนรู้ที่จะเลือกขั้นตอนเหล่านี้ต้องมีอิสระในการทำงาน " +"บางครั้งขั้นตอนที่มีประโยชน์คือการตรวจฟังก์ชันอื่นที่เรียกฟังก์ชันนี้ " +"แทนที่จะแก้โค้ดแล้วคอมไพล์อีกครั้ง " +"ลำดับการเขียนโค้ดใหม่ที่บังคับตายตัวจะตัดทางเลือกนี้ออก " +"รวมถึงพฤติกรรมบางส่วนที่เราอยากให้โมเดลเรียนรู้" + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "เหตุใดวิศวกรรมย้อนกลับจึงน่าสนใจสำหรับการเรียนรู้แบบเสริมกำลัง" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"การสร้างโค้ดขึ้นใหม่ในขอบเขตที่ชัดเจนเป็นสภาพแวดล้อมที่ใช้ศึกษาการเลือกเหล่านี้ได้จริง" +" เมื่อกำหนดเป้าหมายและเวอร์ชันคอมไพเลอร์ไว้แน่นอน " +"การทดลองซอร์สโค้ดหลายแบบจะให้ผลตอบกลับรวดเร็วและทำซ้ำได้ " +"เอเจนต์สามารถคอมไพล์โค้ดที่เสนอ ตรวจส่วนที่ยังต่าง แล้วเลือกขั้นตอนถัดไป" + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"การเรียนรู้แบบเสริมกำลังสามารถฝึกกระบวนการตัดสินใจผ่านคำติชมที่ได้รับ " +"ผู้สมัครที่ยอมรับโดยเช็คที่กำหนดจะให้ผลลัพธ์ที่เป็นรูปธรรมแก่เรา " +"ในขณะที่ลำดับของความพยายามช่วยให้เราสังเกตได้ว่าต้องใช้ความพยายามมากเพียงใดจึงจะบรรลุผลนั้น" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"มีงานวิจัยสนับสนุนแนวทางนี้แล้ว {ph0}LLM4Decompile{ph1} " +"ศึกษาโมเดลที่เชี่ยวชาญการดีคอมไพล์ ส่วน {ph2}AutoDecompiler{ph3} " +"ฝึกการปรับปรุงหลายรอบโดยใช้ผลจากคอมไพเลอร์และการรันโปรแกรม " +"งานเหล่านี้เน้นการกู้คืนพฤติกรรมของโปรแกรม " +"ผมจะใช้เป็นจุดเริ่มต้นสำหรับงานที่เกี่ยวข้อง " +"คือการหาซอร์สโค้ดที่ให้ผลลัพธ์ตรงกับคอมไพเลอร์จากยุคเดิม" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"เพื่อให้บรรลุภารกิจที่กำหนดไว้อย่างชัดเจน " +"เราอาจจำเป็นต้องกำหนดทรัพยากรที่ฟังก์ชันเป็นเจ้าของก่อนหรือออกแบบวิธีใหม่เพื่อสังเกตพฤติกรรมของโปรแกรมขณะทำงาน" +" ตัวอย่างเช่น ใน TH08 ความแตกต่าง {ph0}การชนกัน " +"ทำให้ย้อนกลับไปถึงวิธีที่โปรแกรมดั้งเดิมจัดการการคำนวณจุดลอยตัว{ph1} " +"ก่อนที่ตัวแทนจะทดสอบการแก้ไขที่เป็นประโยชน์ได้ ก็ต้องพิจารณาว่าจะวัดอะไรก่อน" + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "" +"สิ่งนี้ชี้ให้เห็นอีกบทบาทหนึ่งของแบบจำลองที่มีความสามารถในวงกว้าง: " +"ช่วยให้สามารถตรวจสอบปัญหาได้ตั้งแต่แรก เมื่อมีการตรวจสอบแล้ว " +"เราจะสามารถตรวจสอบได้ว่านโยบายการค้นหาที่เรียนรู้จะสามารถนำมาใช้ได้ไกลเพียงใด" + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "เมื่อตัวตรวจสอบความถูกต้องผิดพลาด" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"เมื่อใช้ผลตรวจสำหรับการฝึก " +"ขอบเขตของการตรวจก็กลายเป็นส่วนหนึ่งของสภาพแวดล้อมการเรียนรู้ " +"ผมเรียกข้อมูลอ้างอิงหรือเครื่องมือตรวจนี้ว่า oracle แม้คำตอบจะทำซ้ำได้ " +"เราก็ต้องเข้าใจว่ามันตรวจสอบอะไรจริง ๆ" + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"TH08 แสดงให้เห็นว่าปัญหาอาจซ่อนอยู่นอกขอบเขตการตรวจ " +"บางฟังก์ชันใช้ค่าคงที่แบบ floating-point ที่ผิด " +"แต่ยังผ่านการเปรียบเทียบแบบตรงกันทุกส่วน " +"ตัวเปรียบเทียบปรับแอดเดรสที่ถูกย้ายก่อนตรวจคำสั่ง " +"แต่ตรวจค่าที่แอดเดรสนั้นชี้ไปเฉพาะกรณีที่บันทึกไว้ให้ตรวจอย่างชัดเจน " +"การอ้างอิงค่าคงที่อื่นจึงอาจผ่านโดยไม่ได้ตรวจค่า" + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"เพื่อแก้ไขช่องว่างนี้ {ph0}การตรวจสอบที่กว้างขึ้น{ph1} " +"พบค่าคงที่ที่ไม่ถูกต้องในฟังก์ชันที่ผ่านการตรวจสอบแล้ว ในการคำนวณครั้งหนึ่ง " +"ซอร์สโค้ดที่สร้างขึ้นใหม่ได้เพิ่ม {ph2} ในขณะที่ซอร์สโค้ดดั้งเดิมเพิ่ม {ph3}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}โมเดลที่ได้รับรางวัลจากการตรวจสอบยืนยันแบบเก่าสามารถเรียนรู้ที่จะสร้างการสร้างใหม่ที่ไม่ถูกต้อง{ph1}" +" เราไม่ได้ฝึกโมเดล RL โดยใช้ตัวตรวจสอบนั้น " +"ความล้มเหลวที่เราสังเกตเห็นคือในการตรวจสอบนั่นเอง แต่ถ้าเราใช้เป็นรางวัล " +"จุดบอดเดียวกันก็จะกลายเป็นส่วนหนึ่งของสภาพแวดล้อมการเรียนรู้" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"การทดสอบการทำงานอาจมีจุดบอดที่คล้ายกัน " +"{ph0}การวิจัยโดยใช้การแยกฟัซซีแบบดิฟเฟอเรนเชียลกับตัวถอดรหัส LLM{ph1} " +"พบความแตกต่างด้านพฤติกรรมนอกเหนือจากการทดสอบที่ให้มา " +"ดังนั้นเราจึงจำเป็นต้องเข้าใจการทดสอบที่ผ่านในแง่ของกรณีที่ผ่านการทดสอบ " +"ในทำนองเดียวกัน การจับคู่คำสั่งจะต้องเข้าใจในแง่ของไบต์และข้อมูลที่ตรวจสอบ" + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"ก่อนที่จะใช้การตรวจสอบยืนยันประเภทใดประเภทหนึ่งเป็นรางวัล " +"ฉันจะทดสอบด้วยผลลัพธ์ที่ไม่ถูกต้องโดยเจตนา " +"ฉันยังจะแยกการยอมรับขั้นสุดท้ายออกจากซอร์สโค้ดที่เอเจนต์ AI สามารถแก้ไขได้ " +"โมเดลจะต้องผ่านการตรวจสอบโดยการสร้างโปรแกรมใหม่อย่างถูกต้อง มิฉะนั้น " +"การคัดลอกอาร์เรย์ไบต์จากเป้าหมายอาจหลอกระบบการให้คะแนนที่ไร้เดียงสาโดยไม่ต้องกู้คืนซอร์สโค้ดที่มีประโยชน์" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "" +"{ph0}การปรับปรุงโมเดลและการปรับปรุงเครื่องมือตรวจเป็นส่วนของปัญหาวิจัยเดียวกัน{ph1}" +" ยิ่งโมเดลเก่งในการปรับตัวตามผลตอบกลับที่เราให้ " +"ก็ยิ่งสำคัญที่เราต้องเข้าใจผลตอบกลับนั้น" + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "การเปรียบเทียบที่คุ้มค่า" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"เมื่อตรวจสอบแล้ว ฉันจะเริ่มการเปรียบเทียบในกลุ่มงาน VC7.1 ที่คงที่ ก่อนอื่น " +"ฉันจะสร้างพื้นฐานสำหรับโมเดล AI อเนกประสงค์ที่แข็งแกร่งและโมเดลที่เล็กกว่า " +"การเพิ่มความรู้เกี่ยวกับพื้นที่เก็บข้อมูลให้กับโมเดลขนาดเล็กจะแสดงให้เห็นว่าการเปลี่ยนแปลงในการดึงข้อมูลมีอะไรบ้าง" +" จากนั้น ความเชี่ยวชาญพิเศษภายใต้การดูแลและเวอร์ชันที่ได้รับการฝึกอบรม RL " +"จะให้เราตรวจสอบได้ว่าการฝึกอบรมใดบ้างที่เพิ่มเข้ามา" + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"เพื่อให้การเปรียบเทียบเหล่านี้เป็นข้อมูล " +"แต่ละแบบจำลองจะได้รับหลักฐานและเครื่องมือเป้าหมายที่เหมือนกัน " +"สำหรับการเปรียบเทียบเฉพาะการฝึกอบรม " +"ฉันจะเก็บโมเดลพื้นฐานและความรู้ที่มีอยู่ไว้คงที่เช่นกัน การทดลองซ้ำๆ " +"จะช่วยแยกแยะกลยุทธ์การค้นหาที่เชื่อถือได้จากโซลูชันผู้สมัครที่ประสบความสำเร็จโดยบังเอิญ" + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"จากนั้นฉันจะแยกเงื่อนไขเริ่มต้นสองเงื่อนไข: สร้างฟังก์ชันใหม่จากคำแนะนำ " +"และปิดความแตกต่างสองสามข้อสุดท้ายในแหล่งที่มาที่ได้รับการบำรุงรักษา โมเดล AI" +" เฉพาะทางอาจทำงานได้ดีในงานที่สอง ในขณะที่โมเดล AI " +"เอนกประสงค์ทำงานส่วนใหญ่ที่จำเป็นในการเข้าถึงโมเดลนั้น " +"การวัดแยกกันจะเผยให้เห็นการแบ่งส่วนงานนั้น" + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"ทั้งสองงานต้องมีตัวอย่างทดสอบที่ไม่อยู่ในข้อมูลฝึกและแหล่งข้อมูลสำหรับค้นคืน" +" เกม Touhou ที่เกี่ยวข้องใช้โค้ดเอนจินร่วมกัน " +"การกันเกมหนึ่งออกจากข้อมูลฝึกจึงอาจยังเหลือฟังก์ชันที่เกือบเหมือนกันในชุดฝึก" +" ผมจะกันซอร์สโค้ดที่เกี่ยวข้องทั้งกลุ่มออก " +"และไม่ให้คำตอบที่ผ่านการตรวจแล้วอยู่ในข้อมูลฝึกหรือคลังสำหรับค้นคืน" + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"ผลที่วัดควรเป็นการตรงกันครบทั้งฟังก์ชันซึ่งผ่านการตรวจอย่างอิสระ " +"ให้แต่ละโมเดลมีงบจำนวนโค้ดที่เสนอหรือจำนวนครั้งที่คอมไพล์เท่ากันเพื่อเปรียบเทียบคุณภาพการค้นหา" +" แล้ววัดเวลารวมและต้นทุนรวมซึ่งรวมการคอมไพล์ด้วย " +"เพื่อดูว่าคุณภาพนั้นทำให้งานมีประสิทธิภาพจริงหรือไม่ " +"ต้นทุนการฝึกต้องนับแยกต่างหาก" + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"การวัดทั้งสองมีความสำคัญ ข้อเสนอราคาถูกอาจนำไปสู่ขั้นตอนการทำงานที่มีราคาแพง" +" หากทำให้เกิดการคอมไพล์มากขึ้นซึ่งไม่ได้ให้ข้อมูลที่เป็นประโยชน์ " +"ในทางกลับกัน " +"โมเดลที่ช้ากว่าอาจประหยัดกว่าหากพบว่าการทดสอบมีประโยชน์เร็วกว่านี้ " +"การเปรียบเทียบควรรวมต้นทุนเหล่านี้ด้วย" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"การนับผลลัพธ์ที่ยอมรับยังช่วยรักษาความก้าวหน้าระดับกลางในมุมมองด้วย TH09 " +"{ph0}บันทึกการเล่นซ้ำ-บันทึกผู้สมัคร{ph1} " +"หนึ่งตัวดูมีแนวโน้มดีเนื่องจากฟังก์ชันที่คอมไพล์มีขนาดตามที่คาดหวัง " +"แต่การเปรียบเทียบแบบเต็มยังคงพบความแตกต่างอย่างมาก " +"การเปลี่ยนแปลงวิธีที่คอมไพลเลอร์จัดเรียงคำสั่งยังสามารถทำให้ผู้สมัครมองเข้าไปใกล้มากขึ้นโดยไม่ต้องแก้ไขปัญหาที่ซ่อนอยู่" +" การวินิจฉัยดังกล่าวสามารถเป็นแนวทางในการทดสอบครั้งต่อไปได้ " +"แต่ฉันจะตรวจสอบรางวัลสำหรับการ \"เข้าใกล้\" " +"เทียบกับการตรวจสอบการยอมรับทั้งหมด" + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"ฉันจะสนใจรูปแบบของผลลัพธ์เหล่านี้ หากโมเดล AI " +"เฉพาะทางทำงานได้ดีในตระกูลคอมไพเลอร์ที่คุ้นเคย " +"ข้อได้เปรียบนั้นจะรอดพ้นจากการเปลี่ยนแปลง toolchain หรือไม่ และเมื่อ AI " +"ทั้งสองโมเดลดึงข้อมูลได้ดีแล้ว การฝึกยังเพิ่มอีกเท่าไหร่? " +"คำตอบจะช่วยให้เราตัดสินใจได้ว่าโมเดลแต่ละประเภทมีประโยชน์มากที่สุดที่ใด" + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "สิ่งนี้แนะนำเอเจนต์ AI ประเภทใด" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"หากโมเดลต่างๆ กลายเป็นความช่วยเหลือในขั้นตอนต่างๆ " +"การจัดการที่เป็นประโยชน์อาจเป็นตัวแทนในวงกว้างที่สามารถเข้าถึงโมเดล AI " +"เฉพาะทางได้ เมื่องานกลายมาเป็นการค้นหาคอมไพเลอร์ที่คุ้นเคย " +"งานนั้นก็สามารถถามโมเดล AI เฉพาะทางสำหรับผู้สมัครได้ หากผลลัพธ์ไม่สมเหตุสมผล" +" สารในวงกว้างสามารถกลับไปยังหลักฐานเป้าหมายหรือตรวจสอบการวัดเองได้" + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "" +"ในการจัดการดังกล่าว " +"ความเชี่ยวชาญเฉพาะทางจะกลายเป็นเครื่องมือที่ตัวแทนสามารถเลือกได้ในขณะที่การสืบสวนพัฒนาขึ้น" +" ตัวแทนรักษาอิสระในการเปลี่ยนทิศทางที่ทำให้ความก้าวหน้าก่อนหน้านี้เป็นไปได้" + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"สิ่งนี้เป็นไปตามธรรมชาติจากการเปลี่ยนแปลงทางอุตสาหกรรมที่ฉันอธิบายไว้ในบทความก่อนหน้านี้" +" ความสามารถในการทำการทดสอบอื่นๆ " +"อีกมากมายได้เปลี่ยนแปลงวิธีที่เราจัดระเบียบงาน " +"นอกจากนี้ยังให้เหตุผลแก่เราในการถามว่าการตัดสินใจใดต้องใช้วิจารณญาณกว้างๆ " +"และการตัดสินใจครั้งใดจะปรับปรุงผ่านประสบการณ์ซ้ำแล้วซ้ำเล่ากับงานฝีมือเฉพาะอย่าง" + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"ตอนนี้โมเดลทั่วไปที่เก่งที่สุดมีที่ยืนในวิธีทำงานของผม " +"เพราะแก้ปัญหาที่ก่อนหน้านี้ผมยังแก้ไม่ได้ " +"ความสำเร็จเหล่านี้ทำให้ผมอยากศึกษางานให้ละเอียดขึ้น " +"ว่ามากน้อยแค่ไหนต้องอาศัยความสามารถที่กว้างของโมเดล " +"และมากน้อยแค่ไหนอาจให้โมเดลที่ฝึกเฉพาะงานสร้างโค้ดแบบนี้ทำได้" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "" +"{ph0}ที่เก็บข้อมูลช่วยให้เรามีวิธีทดสอบคำถาม{ph1} " +"ฉันต้องการใช้บันทึกนั้นเพื่อสร้างการเปรียบเทียบและดูสิ่งที่เราเรียนรู้" + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "หลักฐานและการระบุแหล่งที่มาของแบบจำลอง" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"ตัวอย่างจะอธิบายการเปรียบเทียบระดับฟังก์ชันในอดีตที่บันทึกไว้ในการคอมมิตที่เชื่อมโยง" +" การตรวจสอบรันไทม์ทั้งเกมถือเป็นเหตุการณ์สำคัญที่แยกจากกัน " +"แหล่งที่มาและบันทึกการจับคู่ได้รับการตรวจสอบเมื่อวันที่ 13 ตุลาคม พ.ศ. 2569" + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"ป้ายกำกับ TH09 {ph0} หมายถึง GPT-6-Astra โมเดลที่เกี่ยวข้องกับ {ph1} " +"มีการเปลี่ยนแปลงเมื่อเวลาผ่านไป " +"ดังนั้นป้ายกำกับเพียงอย่างเดียวจึงไม่สามารถระบุโมเดลที่ใช้ในการดำเนินการเฉพาะได้" +" ชื่อโมเดลที่ชัดเจนในคอมมิตที่อ้างถึงอื่นๆ ให้การระบุแหล่งที่มาที่บันทึกไว้ " +"ประวัติเหล่านี้ไม่ได้รวมการวัดต้นทุนหรือความพยายามอย่างสม่ำเสมอสำหรับการวิ่งทุกครั้ง" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "" +"{ph0}TH09 อายุการใช้งานของวัตถุชั่วคราว:{ph1} " +"{ph2}การตรวจสอบบริบทก่อนหน้า{ph3} และ " +"{ph4}การสร้างใหม่เสร็จสมบูรณ์ได้รับการตรวจสอบโดยการคอมไพล์ใหม่ทั้งหมดจากแหล่งที่มา{ph5}" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"{ph0}คอลแบ็ก Front ของ TH09:{ph1} {ph2}บริเวณที่ตรวจพบว่ายังไม่ตรง{ph3}, " +"{ph4}กราฟการควบคุมใหม่ของ Astra{ph5} และ " +"{ph6}การตรวจคอมไพล์ซ้ำที่ผ่านการยอมรับ{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}ความรู้เกี่ยวกับคอมไพเลอร์:{ph1} {ph2}TH095 " +"นำพฤติกรรมตัวระบุ-บัคเก็ตกลับมาใช้ใหม่{ph3}, {ph4}TH04 " +"ซอร์สโค้ดของผู้เล่นและลำดับลิงก์เกอร์{ph5} และ {ph6}Luna " +"การสร้างศัตรูใหม่ของ TH09 ใหม่ทั้งหมด ฟังก์ชั่น{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}การตรวจสอบและการวินิจฉัย:{ph1} {ph2}TH08 " +"การตรวจสอบคงที่แบบจุดลอยตัว{ph3}, {ph4}TH08 การตรวจสอบเชิงตัวเลข{ph5} และ " +"{ph6}TH09 การสร้างใหม่เพื่อประหยัดการเล่นซ้ำ{ph7}" + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "" +"การเปรียบเทียบที่เสนอของรุ่นพิเศษและการฝึกอบรม RL เป็นการทดลองในอนาคต " +"ประวัติโครงการเป็นแรงบันดาลใจให้พวกเขา " +"ไม่มีการประเมินแบบจำลองเฉพาะทางที่ได้รับการฝึกอบรมสำหรับบทความนี้" + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "วิศวกรรมย้อนกลับจำเป็นต้องมีโมเดลที่ใหญ่กว่านี้หรือไม่? | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "" +"สิ่งที่ Touhou การสร้างใหม่สอนฉันเกี่ยวกับโมเดลทั่วไป โมเดลผู้เชี่ยวชาญ " +"และการเรียนรู้ที่จะเสนอสมมติฐานที่ดีกว่าจากคำติชมของคอมไพเลอร์" + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "ในหน้านี้" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "แบบจำลองและเรียงความวิศวกรรมย้อนกลับ" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "การทดลองสร้างใหม่ที่เลือก" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "กลับขึ้นด้านบน" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "" +"{ph0}บันทึกหลักฐานโดยละเอียด{ph1} มีผลการเปรียบเทียบและบริบทของการทดลอง" + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "โดย N0zoM1z0 · 13 ตุลาคม 2026 · ฉบับร่างสำหรับตรวจทาน" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "คู่มือการติดตั้ง" diff --git a/website/locales/tr/messages.po b/website/locales/tr/messages.po index e4d0ba4a0..9d71134ed 100644 --- a/website/locales/tr/messages.po +++ b/website/locales/tr/messages.po @@ -32,18 +32,18 @@ msgid "Thoughts on reverse engineering." msgstr "Tersine mühendislik üzerine düşünceler." #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "Oyun rekonstrüksiyonu{ph0}Deneme" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "Tersine mühendislikte endüstri devrimi" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " @@ -53,19 +53,20 @@ msgstr "" "yapılandırılması bana projeler arasında birleşen aracılar, doğrulama ve " "bilgi hakkında bilgi verdi." -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "Makaleyi okuyun" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "Başlangıç N0zoM1z0 * 10 Ekim 2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -101,6 +102,8 @@ msgstr "" "deneyimlerden yararlanma." #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -137,6 +140,7 @@ msgstr "" "mühendislik yapın." #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -157,6 +161,7 @@ msgid "REA home" msgstr "REA ana sayfası" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -177,6 +182,7 @@ msgid "Main navigation" msgstr "Ana menü" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -197,6 +203,7 @@ msgid "REA on GitHub" msgstr "GitHub’da REA" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -217,6 +224,7 @@ msgid "Join REA on Discord" msgstr "REA Discord topluluğuna katıl" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -236,7 +244,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "REA’yı X’te takip et" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "Başa dön" @@ -11605,6 +11613,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "Aynı aralık: 256 ÷ 16 = 16 açı birimi = 22,5 °" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -11625,6 +11634,7 @@ msgid "Showcases" msgstr "Örnekler" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -11645,6 +11655,7 @@ msgid "Blog" msgstr "Blog" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -11665,6 +11676,7 @@ msgid "Get started" msgstr "Başlangıç" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -11684,7 +11696,8 @@ msgctxt "shared" msgid "Guides" msgstr "Rehberler" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -11704,7 +11717,8 @@ msgctxt "shared" msgid "Source" msgstr "Kaynak kod" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -11724,7 +11738,8 @@ msgctxt "shared" msgid "MIT license" msgstr "MIT lisansı" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -11744,7 +11759,8 @@ msgctxt "shared" msgid "Join the community" msgstr "Topluluğa katıl" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -12706,6 +12722,1376 @@ msgstr "" " kaydedilen trafiği ajanınızla incelemek için Everywhere MCP sunucusunu " "bağlayın." +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "Uzmanlaşmış modeller{ph0}Deneme" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "Tersine mühendislik için daha büyük bir model gerekli mi?" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "" +"Touhou yeniden yapılandırma deneyiminden genel amaçlı modeller, uzmanlaşmış " +"modeller ve derleyici geri bildiriminden öğrenme üzerine düşünceler." + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Yazan N0zoM1z0 · 13 Ekim 2026" + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "İçeriğe geç" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "" +"{ph0}Ana Sayfa{ph1} / {ph2}Blog{ph3} / Modeller ve tersine mühendislik" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "Deneme" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "Tersine mühendisliğin daha büyük bir modele ihtiyacı var mı?" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Yazan N0zoM1z0 · 13 Ekim 2026" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "Önemli noktalar" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "" +"{ph0}Model yeteneği, bir yapay zeka aracısının hangi hipotezleri " +"önerebileceğini etkiler.{ph1} Daha sonraki oturumlarda, daha önceki " +"çalışmaların çözümsüz bıraktığı sorunlar çözüldü." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "" +"{ph0}Tanıdık bir derleyici, özel bir modelin öğrenilmesi için somut modeller" +" sunar.{ph1} Bazı tam makine kodu eşleşmeleri, belirli, yeniden " +"kullanılabilir kaynak kodu modellerine bağlıdır." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "" +"{ph0}Adil bir karşılaştırmaya veri deposu bilgisini dahil edin.{ph1} İyi " +"bilgi erişimine sahip daha küçük bir model, ilerleme kaydetmek için zaten " +"yeterli bilgiye sahip olabilir." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "" +"{ph0}Modeli, bir sonraki faydalı deneyi seçecek şekilde eğitin ve doğrulama " +"denetleyicisini test edin.{ph1} Geri bildirim, yalnızca denetleyicinin doğru" +" şeyleri doğruladığı ölçüde faydalıdır." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "" +"{ph0}Doğrulanmış yeniden yapılandırma sonuçlarını zaman ve maliyetle " +"birlikte değerlendirin.{ph1} Yapay zeka aracısı iş akışının tamamı için " +"ölçmek istediğim şey bu." + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "Bu makalede" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}Daha güçlü modeller neyi değiştirdi?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}Neden uzmanlaşalım?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}Bu deneyim nerede saklanmalı?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}Bir sonraki faydalı deneyi öğrenmek{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}Tersine mühendislik ve takviyeli öğrenme{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}Doğrulama denetleyicisi yanlış olduğunda{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}Çalıştırılmaya değer bir karşılaştırma{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}Bu ne tür bir yapay zeka ajanını akla getiriyor?{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "Daha güçlü modeller neyi değiştirdi?" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"Ağustos 2026'dan bu yana, bir aracının bir programa erişim ve onun " +"çalışmasını kontrol etmenin bir yolu ile ne kadar tersine mühendislik " +"gerçekleştirebileceğini araştırıyorum. Deneyimlerimin çoğu, özellikle Touhou" +" olmak üzere oyunların yeniden yapılandırılmasından geliyor. Modelleri " +"değiştirdiğimde, depolar her oturumda kurtarılanların kaydını tuttu." + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"Bu çalışmanın büyük bir kısmı tam olarak yeniden yapılanmayı amaçlamaktadır:" +" Bakımı yapılan kaynağı, sabit versiyonlara sahip tarihsel bir araç zinciri " +"altında derliyoruz ve hedef işlevi yeniden üretip üretmediğini kontrol " +"ediyoruz. Önceki çalışmaların durduğu yerde daha sonraki bir model başarılı " +"olduğunda, kaynak değişiklikleri bu ilerlemeyi neyin mümkün kıldığını " +"gösterir." + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "Geçici değişkenler örtüşen yaşam sürelerine ihtiyaç duyuyordu" + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"TH09 saldırı fonksiyonunun mantığının büyük bir kısmı zaten yeniden " +"oluşturulmuştu, ancak derleyici hala geçici sonuçları orijinalinden farklı " +"şekilde saklıyordu. Geriye kalan sorun, bu sonuçların ne kadar süreyle canlı" +" kalması gerektiği ve depolarının ne zaman yeniden kullanılabileceğiydi." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"Bir {ph0}GPT-6-Sol oturum kaydı{ph1}, birkaç sıradan kaynak kodu " +"düzenlemesini test ettikten sonra bu uyumsuzluğu bildirdi. {ph2}GPT-6.1-Sol " +"sorunu tekrar incelediğinde{ph3}, bu geçici değişkenlerin yaşam süreleri " +"hakkında yararlı bir hipotez öne sürdü." + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"İşlev geçici sonuçlar üretti ve bunları animasyon konumlarına kopyaladı. " +"C++'da geçici bir sonuç, onu kullanan ifade bitene kadar canlı kalır. Gerçek" +" işlemleri tek bir ifadede gruplandırmak bu sonuçları bir arada canlı tuttu," +" böylece derleyici artık aynı depolamayı hepsi için yeniden kullanamıyordu." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"Sonuçlardan biri, daha sonra çarpışma kontrolleri için kullanılan bir " +"değerle depolamayı hâlâ paylaşıyordu. Bu değere kendi ömrünü vermek, kalan " +"örtüşmeyi çözdü. Birkaç hedefli denemeden sonra, {ph0}kaynaktan yapılan " +"temiz bir yeniden derleme, tam işlevin eşleştiğini doğruladı{ph1}." + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"Keşif ve testlerin birbirini nasıl desteklediğiyle ilgileniyorum. Geçici " +"nesne yaşam süreleri hakkındaki hipotez, yapay zeka ajanına yeni bir yön " +"verdi. Derleyici geri bildirimi, bu hipotezi eşleşen bir kaynak kodu " +"düzenlemesine dönüştürmeye yardımcı oldu." + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "Farklı bir kontrol akışı grafiği" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"İkinci bir TH09 işlevi, bu yeni yönün neden önemli olabileceğini gösterir. " +"Buradaki engel, birden fazla şubenin nihai çalışmalarını paylaşmasıydı. " +"{ph0}GPT-6.1-Sol'nin önceki çalışması{ph1} işlevin bazı kısımlarını " +"eşleştirdi ancak dallar yine de orijinalinden farklı bir şekilde birleşti." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}GPT-6-Astra çevredeki kontrol akışı grafiğini değiştirdi{ph1}. Ana " +"yollar artık paylaşılan bir son güncellemeye ve geri dönüşe yol açıyordu. Bu" +" kaynak yapısında derleyici, dalları orijinaldekiyle aynı şekilde " +"birleştirdi. İşlevin tamamı eşleşti ve {ph2}ayrı bir yeniden oluşturma " +"kontrolü bunu doğruladı{ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}Temsili değiştirmek daha verimli bir arama alanı açtı.{ph1} Her iki " +"durum da bana genel model yeteneğini ciddiye almam için bir neden veriyor: " +"Bir temsilci, çevredeki işi ifade etmenin daha iyi bir yolunu bulmadan önce " +"yerel varyasyonları uzun süre denemeye devam edebilir." + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"Sonraki oturumlar önceki kaynak kodu ve kaydedilmiş başarısız denemeleri de " +"devraldı. Bu birikim avantajlarının bir parçasıydı. Geçmiş, keşifleri ve " +"doğrulamalarını incelememizi sağlar; kontrollü bir karşılaştırma ise modelin" +" etkisini devraldığı deneyimin etkisinden ayırmaya yardımcı olur." + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"Soruyu benim için ilginç kılan da bu. Yeni bir temsil bulma konusunda bir " +"miktar ilerleme sağlandı. Geriye kalan çalışmaların çoğu, farklı kaynak kodu" +" düzenlemelerinin tanıdık bir derleyiciye karşı test edilmesini içeriyordu. " +"Bunun ne kadarı geniş muhakeme yeteneği gerektiriyor? Bir model, o derleyici" +" ve kodla tekrar tekrar çalışarak ne kadar öğrenebilir?" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "Özel bir yapay zeka modeli neden başarılı olabilir?" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"Touhou bize bu deneyimin yardımcı olmasını beklememiz için somut bir neden " +"veriyor. Oyun kodunun büyük bir kısmı aynı yazardan (ZUN) geliyor, " +"dolayısıyla yinelenen alışkanlıklar makul bir başlangıç ​​varsayımıdır. " +"Depolar bunu yararlı örneklerle desteklemektedir: İlgili döngüler ve " +"yardımcı düzenlemeler, oyunlar arasında hipotezler sağlamıştır." + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "" +"Derleyiciyi dahil ettiğimizde bu kaynak kalıpları daha spesifik hale gelir. " +"Belirli bir sürüm ve seçenekler kümesi altında, kaynaktaki küçük " +"değişiklikler makine kodunda tekrarlanabilir farklılıklara neden olabilir. " +"Bu farklılıkların bazıları şaşırtıcı derecede belirsizdir." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"Örneğin TH095'de, {ph0}yerel bir değişkenin adı bile VC7.1'nin onu nerede " +"sakladığını etkileyebilir{ph1}. Bildiriminin taşınması depolama düzenini " +"çözmedi. Ancak daha önceki bir arka plan işlevi, derleyicinin seçimini " +"etkileyen bir adlandırma modelini ortaya çıkarmıştı. Bu, {ph2}yeniden inşa " +"etmek{ph3}{ph4} için daha umut verici bir hipotez önerdi." + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "" +"Dosya boyutu değişkeni için bu kalıbın yeniden kullanılması, depolama alanı " +"eklemeden gerekli düzeni oluşturdu. Daha sonra tam işlev eşleşti." + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "" +"Bu, genel amaçlı bir yapay zeka modelinin sorunla ilk karşılaştığında " +"bilemeyeceği çok özel bir ayrıntıdır. Bu derleyici için uzmanlaşmış bir " +"model, bu tür birçok durumu görebilir ve hangi kaynak kodu varyasyonlarının " +"ilk önce test edilmeye değer olduğunu öğrenebilir." + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"Davranışı zaten anladığımız son eşleştirme problemlerinde bu fırsat " +"özellikle açıktır. Daha sonra bu derleyicinin hangi sıradan kaynak kodu " +"düzenlemesini gözlemlenen talimatlara dönüştürdüğünü soruyoruz. Uzmanlaşma, " +"modelin bu formları daha verimli bir şekilde önermesine yardımcı olurken, " +"hedef hâlâ hangi hipotezlerin hayatta kalacağını belirliyor." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"Yararlı kalıplar bağlamlarını korumalıdır. TH08, TH095 ve TH09’dan daha eski" +" bir Visual C++ sürümü kullanır. TH04 ise DOS dönemine ait başka bir " +"derleyici kullanır. {ph0}Oyuncu kodunun yeniden yapılandırılması{ph1}, " +"kaynak kalıpları ve kodun çalıştırılabilir dosyaya nasıl bağlandığı hakkında" +" farklı hipotezler gerektirdi. Aynı yazar bize bir başlangıç varsayımı " +"verir; bunun geçerli olup olmadığını her hedefte kontrol ederiz. Uzman model" +" bu bağlamları ayırt etmeyi öğrenmelidir." + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "Bu deneyim nerede saklanmalı?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"Bu kalıpları model eğitimi yoluyla öğretmeye karar vermeden önce, " +"halihazırda depoda tuttuğumuz bilgilere bakardım. {ph0}Önceki makalemde{ph1}" +" bunun projenin çalışma belleği haline geldiğini yazmıştım. Bu hafıza, " +"derleyici derslerini, kaynağı ve onları faydalı kılan başarısız deneyleri " +"içerir." + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"Bir aracı, bu kaydı alarak bilinen bir sonuçla başlayabilir ve bu sonuca " +"nasıl ulaştığımızı inceleyebilir. Aynı bağlamda halihazırda başarısız olan " +"alternatiflerden de kaçınılabilir. Başlangıç ​​noktası, modelin eğitilmiş " +"parametrelerini değiştirmeden iyileşir." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"TH09'nin düşman yaratma işlevi yeniden yapılandırılırken, bir " +"{ph0}GPT-6-Luna-max oturumu{ph1} ilgili TH08 kaynak kodundan bir hipotez " +"aldı. Önceki kod, döngünün nasıl organize edileceğini ve içindeki arızaların" +" nasıl ele alınacağını öneriyordu. TH09'in kendi kanıtları oyuna özgü " +"ayrıntıları sağladı. Kaynaktan yapılan yeniden derlemeler, işlevin tamamının" +" eşleştiğini doğruladı." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}\"Model, derleyici tuhaflığını bilmiyordu\" ve \"model bunu " +"kullanamadı\" farklı sorunlardır.{ph1} Geri getirme ilk sorunu çözebilir, " +"ancak bu gerçeği yararlı bir adaya dönüştürmek yine de çalışma gerektirir. " +"Aday kaynak kodu başarısız olursa modelin bir sonraki denemesinde sonucun ne" +" anlama geldiğine karar vermesi gerekir. İlgili modeli bilmek bu sürecin " +"yalnızca başlangıcıdır." + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"Bu nedenle, herhangi bir karşılaştırmaya, iyi geri çağırma özelliğine sahip," +" daha küçük, genel amaçlı bir yapay zeka modelini dahil ederim. Aynı deneyim" +" kitaplığını ona vermek, eğitimin ne gibi katkılar sağladığını belirlememize" +" yardımcı olacaktır: daha iyi aday oluşturma, geri bildirim sonrasında daha " +"iyi kararlar veya her ikisi." + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "Bir sonraki faydalı deneyi öğrenmek" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"Geri bildirim sonrasında verilen kararlar, üzerinde çalışmayı en çok " +"istediğim şeylerdir. Failsel yeniden yapılanmada model bir açıklama önerir " +"ve bunu programa karşı test eder. Aday kaynak kodu başarısız olsa bile " +"sonuç, kalan olasılıkları daraltabilir ve bir sonraki deneyin daha yararlı " +"olmasını önerebilir." + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "" +"Geçici sonuçlar örneğini tekrar düşünün. Son kaynağı işe yarayan düzenlemeyi" +" gösteriyor ancak bu kaynağa giden yol daha fazla bilgi içeriyor. Aşağıdaki " +"deneylerin her biri, hala neyin değişmesi gerektiğinin belirlenmesine " +"yardımcı oldu." + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "Deney" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "Sonucunun bize öğrettikleri" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "Sonuçları kopyalamanın farklı bir yolunu deneyin" + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "Kopya kodu değişir ancak işlev hâlâ farklıdır." + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "Döndürülen değerleri doğrudan kullanın" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "" +"Kopyalama orijinal düzeni takip eder ancak geçici depolama yine de " +"farklıdır." + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "Tüm geçici değişkenleri aynı anda geçerli tutun" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "" +"Ayrı bir depolamaya sahipler, ancak bir tanesi daha sonra çarpışma " +"kontrolleri için kullanılan bir değerle örtüşüyor." + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "Çarpışma kontrolü değerini ayrı tutun" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "" +"Kaynaktan alınan temiz bir yeniden derleme, eşleşmenin tamamını doğrular." + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "" +"Yukarıdaki saldırı fonksiyonunun yeniden yapılandırılmasından bize " +"öğrettiklerine göre gruplandırılmış seçilmiş deneyler." + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"Bu sırayı tutan bir eğitim kaydı, tek başına nihai kaynaktan daha fazlasını " +"öğretebilir. Önerilen her değişikliği gözlemlenen bir sonuca ve bir sonraki " +"karara bağlar. Etkisiz varyasyonları korumak da önemlidir: Daha sonraki bir " +"temsilciye, o bağlamda hangi hipotezlerin zaten test edildiğini söylerler." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}Modelin geri bildirimi nasıl kullanacağını öğrenmesini isterim.{ph1} " +"Nötr bir sonuç, varyasyonun yeniden değerlendirilmesi için bir nedendir; " +"değişen bir uyumsuzluk başka bir nedene işaret edebilir. Yerel düzenlemeler " +"bilgilendirici olmayı bıraktığında, aracının kaynak temsilini yeniden gözden" +" geçirebilmesi veya kanıtları yeniden inceleyebilmesi gerekir." + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"Bu seçimleri yapmayı öğrenmek özerklik gerektirir. Bazen bir sonraki yararlı" +" adım, başka bir düzenleme derlemek yerine başka bir arayanı incelemektir. " +"Gerekli yeniden yazma işlemlerinin katı bir dizisi, modelin öğrenmesini " +"istediğimiz davranışın bir kısmıyla birlikte bu seçimi de ortadan " +"kaldıracaktır." + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "Takviyeli öğrenme için tersine mühendislik neden ilgi çekicidir?" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"Sınırlı yeniden yapılandırma bize bu seçimleri incelemek için pratik bir " +"ortam sağlar. Hedef ve derleyici sürümleri sabitlendikten sonra birçok " +"kaynak denemesi hızlı, tekrarlanabilir geri bildirim üretir. Temsilci bir " +"adayı derleyebilir, uyumsuzluğu inceleyebilir ve bu gözlemi bir sonraki " +"adımını seçmek için kullanabilir." + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"Takviyeli öğrenme, aldığı geri bildirim yoluyla karar verme sürecini " +"eğitebilir. Belirli bir kontrolle kabul edilen bir aday bize somut bir sonuç" +" verirken, denemelerin sırası bu sonuca ulaşmak için ne kadar çaba " +"harcandığını gözlemlememize olanak tanır." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"Bu yönü destekleyen araştırmalar zaten var. {ph0}LLM4Decompile{ph1} kaynak " +"koda dönüştürme için uzmanlaşmış modelleri inceliyor. " +"{ph2}AutoDecompiler{ph3}, derleyici ve yürütme geri bildirimini kullanarak " +"çok turlu iyileştirmeyi eğitir. Çalışmaları fonksiyonel iyileşmeye " +"odaklanıyor. Bu çalışma için bunları, tarihsel bir derleyicinin çıktısıyla " +"eşleşen kaynağı bulma görevi için bir başlangıç ​​noktası olarak " +"kullanacağım." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"Böylesine iyi tanımlanmış bir göreve ulaşmak için öncelikle bir fonksiyonun " +"hangi kaynaklara sahip olduğunu belirlememiz veya programın çalışırkenki " +"davranışını gözlemlemek için yeni bir yöntem tasarlamamız gerekebilir. " +"Örneğin TH08'de, bir {ph0}çarpışma farkı, orijinal programın kayan nokta " +"hesaplamalarını{ph1} nasıl işlediğini ortaya çıkardı. Aracının yararlı bir " +"düzeltmeyi test edebilmesi için önce neyi ölçeceğini bulması gerekiyordu." + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "" +"Bu, geniş kapsamlı bir model için başka bir rol öneriyor: ilk etapta sorunun" +" kontrol edilebilir olmasına yardımcı olmak. Bu kontrol bir kez mevcut " +"olduğunda, öğrenilmiş bir arama politikasının bununla ne kadar ileri " +"gidebileceğini araştırabiliriz." + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "Doğrulama denetleyicisi yanlış olduğunda" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"Bir kontrolü eğitimde kullandığımızda, kapsamı da öğrenme ortamının bir " +"parçası olur. Böyle bir referansa veya doğrulayıcıya oracle diyorum. " +"Tekrarlanabilir bir yanıt bile gerçekte neyi doğruladığına göre " +"anlaşılmalıdır." + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"TH08 bu kapsamın dışında ne kadar şeyin saklanabileceğini gösterdi. Yeniden " +"oluşturulan bazı işlevler, tam karşılaştırmalarını yanlış kayan sabitlerle " +"geçti. Karşılaştırıcı, talimatları kontrol etmeden önce yeniden " +"konumlandırılan adresleri ayarladı, ancak bu adreslerin arkasındaki " +"değerleri yalnızca doğrulama için açıkça kaydedildiklerinde kontrol etti. " +"Diğer gerçek referanslar, değerleri incelenmeden geçebilir." + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"Bu boşluğu gidermek için, {ph0}daha geniş bir denetim{ph1}, doğrulamayı " +"zaten geçmiş işlevlerde hatalı sabitler buldu. Bir hesaplamada, yeniden " +"oluşturulan kaynak kodu {ph2}'yi eklerken, orijinali {ph3}'ü ekledi." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}Eski doğrulama denetimiyle ödüllendirilen bir model, hatalı bir yeniden" +" yapılandırma üretmeyi öğrenebilir.{ph1} Bu denetleyiciyi kullanarak bir RL " +"modelini eğitmedik. Gözlemlediğimiz başarısızlık kontrolün kendisindeydi. " +"Ancak bunu bir ödül olarak kullanırsak aynı kör nokta öğrenme ortamının bir " +"parçası haline gelecektir." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"Fonksiyonel bir testin de benzer bir kör noktası olabilir. {ph0}LLM kod " +"çözücüler üzerinde diferansiyel bulanıklaştırmayı kullanan araştırma{ph1}, " +"sağlanan testlerin dışında davranışsal farklılıklar buldu. Bu nedenle geçme " +"testini, uyguladığı durumlar açısından anlamamız gerekir. Benzer şekilde, " +"bir talimat eşleşmesinin, doğruladığı baytlar ve veriler açısından " +"anlaşılması gerekir." + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"Her iki doğrulama kontrolünü de ödül olarak kullanmadan önce, bunu kasıtlı " +"olarak yanlış sonuçlarla test ederim. Ayrıca nihai kabulü, yapay zeka " +"aracısının düzenleyebileceği kaynak kodundan ayrı tutacağım. Model, programı" +" doğru bir şekilde yeniden oluşturarak doğrulamayı geçmelidir. Aksi " +"takdirde, hedeften bir bayt dizisinin basitçe kopyalanması, yararlı kaynak " +"kodunu kurtarmadan saf bir puanlama sistemini kandırabilir." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "" +"{ph0}Öğreneni geliştirmek ve doğrulama denetleyicisini geliştirmek aynı " +"araştırma probleminin bir parçasıdır.{ph1} Öğrenci, ona verdiğimiz geri " +"bildirimi optimize etme konusunda daha iyi hale geldikçe, geri bildirimin " +"anlaşılması da daha önemli hale gelir." + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "Çalıştırılmaya değer bir karşılaştırma" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"Bu kontroller uygulandığında, karşılaştırmaya sabit bir VC7.1 görev ailesi " +"üzerinde başlayacağım. İlk olarak, güçlü bir genel amaçlı yapay zeka modeli " +"ve daha küçük bir model için temeller oluşturacaktım. Daha küçük modele depo" +" bilgisinin eklenmesi, geri almanın ne gibi değişikliklere yol açtığını " +"gösterecektir. Buradan itibaren, denetimli uzmanlık ve RL ile eğitilmiş bir " +"sürüm, eğitimin neleri eklediğini incelememize olanak tanır." + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"Bu karşılaştırmaları bilgilendirici kılmak için her model aynı hedef " +"kanıtları ve araçları alacaktır. Eğitime özel karşılaştırmalar için temel " +"modeli ve mevcut bilgiyi de sabit tutardım. Tekrarlanan denemeler, güvenilir" +" bir arama stratejisini şans eseri başarılı olan aday bir çözümden ayırmaya " +"yardımcı olacaktır." + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"Daha sonra iki başlangıç koşulunu ayıracağım: bir fonksiyonu talimatlarından" +" yeniden oluşturmak ve korunan kaynaktaki son birkaç farklılığı kapatmak. " +"Özel bir yapay zeka modeli ikinci görevde mükemmel olabilirken, genel amaçlı" +" bir yapay zeka modeli, ona ulaşmak için gereken işin çoğunu yapar. Bunları " +"ayrı ayrı ölçmek o iş bölümünü ortaya çıkaracaktır." + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"Her iki görevin de eğitim ve erişim dışında bırakılan test örneklerine " +"ihtiyacı vardır. İlgili Touhou oyunları motor kodunu paylaşır. Bir oyunu " +"eğitimden hariç tutmak, eğitim setinde neredeyse aynı işlevlerin kalmasına " +"neden olabilir. Bunun yerine, ilgili kaynak kodu gruplarının tamamını hariç " +"tutar ve doğrulanmış yanıtlarını hem eğitim verilerinin hem de erişim " +"kütüphanesinin dışında tutardım." + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"Bu örnekler için sonuç, eksiksiz, bağımsız olarak doğrulanmış eşleşmeler " +"olacaktır. Aday teklifleri veya derleme girişimleri için eşit bütçeler, " +"arama kalitesinin karşılaştırılmasına yardımcı olacaktır. Derleme de dahil " +"olmak üzere toplam süre ve maliyetin ölçülmesi, bu kalitenin verimli bir iş " +"akışı üretip üretmediğini gösterecektir. Eğitim maliyetleri ayrı olarak " +"ölçülmelidir." + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"Her iki ölçüm de önemlidir. Ucuz bir teklif, hiçbir yararlı bilgi sağlamayan" +" daha fazla derlemeye neden olursa pahalı bir iş akışına yol açabilir. " +"Tersine, daha yavaş bir model, yararlı bir deneyi daha erken bulursa daha " +"ekonomik olabilir. Karşılaştırma bu maliyetleri içermelidir." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"Kabul edilen sonuçların sayılması aynı zamanda ara ilerlemeyi de perspektif " +"içinde tutar. Bir TH09 {ph0}tekrar oynatma-kaydetme adayı{ph1}, derlenmiş " +"işlevin beklenen boyuta sahip olması nedeniyle umut verici görünüyordu, " +"ancak tam bir karşılaştırma yine de önemli farklılıklar buldu. Derleyicinin " +"talimatları düzenleme biçimindeki değişiklikler, altta yatan sorunu çözmeden" +" adayın daha yakından bakmasını da sağlayabilir. Bu tür teşhisler bir " +"sonraki deneye rehberlik edebilir, ancak \"yaklaşmanın\" herhangi bir " +"ödülünü tam kabul kontrolüne göre doğrularım." + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"Bu sonuçlardaki model ilgimi çeker. Özel bir yapay zeka modeli tanıdık bir " +"derleyici ailesinde başarılı olursa, bu avantaj bir takım zinciri " +"değişikliğinden sonra da ayakta kalabilir mi? Her iki yapay zeka modeli de " +"iyi bir erişime sahip olduğunda, eğitimin hâlâ ne kadar katkısı olur? " +"Cevaplar, her model türünün en yararlı olduğu yerin neresi olduğuna karar " +"vermemize yardımcı olacaktır." + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "Bu ne tür bir yapay zeka ajanını akla getiriyor?" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"Modellerin farklı aşamalarda yardımcı olduğu ortaya çıkarsa, özel bir yapay " +"zeka modeline erişimi olan geniş bir temsilci yararlı bir düzenleme " +"olabilir. Bir görev tanıdık bir derleyici araması haline geldiğinde, adaylar" +" için özel yapay zeka modelini isteyebilir. Sonuçların artık bir anlamı " +"kalmazsa, daha geniş kapsamlı temsilci hedef kanıtlara geri dönebilir veya " +"ölçümün kendisini araştırabilir." + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "" +"Bu düzenlemede uzmanlaşma, soruşturma geliştikçe temsilcinin seçebileceği " +"bir araç haline gelir. Temsilci, daha önceki atılımları mümkün kılan yön " +"değiştirme özgürlüğünü elinde tutar." + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"Bu, doğal olarak önceki makalede anlattığım endüstriyel değişimin sonucudur." +" Daha fazla deney yürütebilmek, işi organize etme şeklimizi değiştirir. Aynı" +" zamanda bize, hangi kararların geniş muhakeme gerektirdiğini ve " +"hangilerinin belirli bir zanaatta tekrarlanan deneyimlerle geliştirildiğini " +"sormamız için bir neden de verir." + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"Şimdilik en güçlü genel model, daha önce çözemediğim sorunları çözerek iş " +"akışımda yerini kazandı. Bu başarılar süreci daha yakından incelemek " +"istememe yol açıyor: Ne kadarı modelin geniş yeteneklerine bağlıydı? Ne " +"kadarı bu yeniden yapılandırma türüne özel olarak eğitilmiş bir model " +"tarafından yapılabilirdi?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "" +"{ph0}Depolar bize soruyu test etmemiz için bir yol sağlıyor.{ph1} Bu kaydı " +"karşılaştırmayı oluşturmak ve ne öğrendiğimizi görmek için kullanmak " +"istiyorum." + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "Kanıt ve model ilişkilendirme" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"Örnekler, bağlantılı taahhütlerde kaydedilen geçmiş işlev düzeyi " +"karşılaştırmalarını açıklamaktadır. Tüm oyun çalışma zamanı kontrolleri ayrı" +" kilometre taşlarıdır. Kaynak ve eşleşen kayıtlar 13 Ekim 2026'da incelendi." + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"TH09 etiketi {ph0}, GPT-6-Astra anlamına gelir. {ph1} ile ilişkilendirilen " +"model zaman içinde değiştiği için etiket tek başına belirli bir çalıştırmada" +" kullanılan modeli tanımlayamaz. Belirtilen diğer taahhütlerdeki açık model " +"adları, kaydedilen atıfları sağlar. Bu geçmişler, her çalıştırma için " +"tutarlı maliyet veya çaba ölçümlerini içermez." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "" +"{ph0}TH09 geçici nesne yaşam süreleri:{ph1} {ph2}önceki bağlam " +"incelemesi{ph3} ve {ph4}kaynaktan temiz bir yeniden derlemeyle doğrulanan " +"tam yeniden yapılandırma{ph5}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"{ph0}TH09 Front geri arama:{ph1} {ph2}eşleşmeyen tanılama bölgeleri{ph3}, " +"{ph4}Astra'nin yeni kontrol akışı grafiği{ph5} ve onun {ph6}kabul edilen " +"yeniden derleme kontrolü{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}Derleyici bilgisi:{ph1} {ph2}TH095 tanımlayıcı grubu davranışının " +"yeniden kullanımı{ph3}, {ph4}TH04 oyuncu kaynak kodu ve bağlayıcı " +"sırası{ph5} ve {ph6}Luna'nin TH09'nin düşman oluşturma işlevini tamamen " +"yeniden yapılandırması{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}Kontroller ve teşhisler:{ph1} {ph2}TH08 kayan nokta sabiti " +"denetimi{ph3}, {ph4}TH08 sayısal inceleme{ph5} ve {ph6}TH09 yeniden " +"oynatmayı kaydeden yeniden yapılandırma{ph7}." + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "" +"Özel modellerin ve RL eğitiminin önerilen karşılaştırmaları gelecekteki " +"deneylerdir. Proje geçmişleri onları motive ediyor. Bu makale için hiçbir " +"eğitimli özel model değerlendirilmemiştir." + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "Tersine mühendisliğin daha büyük bir modele ihtiyacı var mı? | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "" +"Touhou yeniden yapılandırma bana genel modeller, uzman modeller ve derleyici" +" geri bildirimlerinden daha iyi hipotezler önermeyi öğrenme hakkında neler " +"öğretti?" + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "Bu sayfada" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "Modeller ve tersine mühendislik makalesi" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "Seçilmiş yeniden yapılanma deneyleri" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "Başa dön" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "" +"{ph0}Ayrıntılı kanıt notları{ph1}, kaydedilen karşılaştırmaları ve " +"deneylerin bağlamını içerir." + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "N0zoM1z0 · 13 Ekim 2026 · İnceleme taslağı" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "Kurulum rehberi" diff --git a/website/locales/uk/messages.po b/website/locales/uk/messages.po index a5fae5c80..55afe918d 100644 --- a/website/locales/uk/messages.po +++ b/website/locales/uk/messages.po @@ -32,18 +32,18 @@ msgid "Thoughts on reverse engineering." msgstr "Думки про реверс-інжиніринг." #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "Реконструкція гри{ph0}Вигадування" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "Промислова революція в області реверс-інжинірингу" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " @@ -52,19 +52,20 @@ msgstr "" "Чому мене навчив посібник з оновлення та реконструкції TH08, TH095 та TH04 " "про агентів, перевірку та знання, які використовуються в різних проектах." -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "Прочитайте статтю" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "Автор: N0zoM1z0 · 10 жовтня 2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -100,6 +101,8 @@ msgstr "" " і агентами штучного інтелекту." #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -136,6 +139,7 @@ msgstr "" "допомогою вашого програміста." #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -156,6 +160,7 @@ msgid "REA home" msgstr "Головна REA" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -176,6 +181,7 @@ msgid "Main navigation" msgstr "Основна навігація" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -196,6 +202,7 @@ msgid "REA on GitHub" msgstr "REA на GitHub" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -216,6 +223,7 @@ msgid "Join REA on Discord" msgstr "Приєднатися до REA в Discord" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -235,7 +243,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "Стежити за REA в X" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "Нагору" @@ -11684,6 +11692,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "Однакова відстань: 256 ÷ 16 = 16 кутових одиниць = 22,5°" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -11704,6 +11713,7 @@ msgid "Showcases" msgstr "Приклади" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -11724,6 +11734,7 @@ msgid "Blog" msgstr "Блог" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -11744,6 +11755,7 @@ msgid "Get started" msgstr "Почати" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -11763,7 +11775,8 @@ msgctxt "shared" msgid "Guides" msgstr "Посібники" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -11783,7 +11796,8 @@ msgctxt "shared" msgid "Source" msgstr "Вихідний код" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -11803,7 +11817,8 @@ msgctxt "shared" msgid "MIT license" msgstr "Ліцензія MIT" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -11823,7 +11838,8 @@ msgctxt "shared" msgid "Join the community" msgstr "Приєднатися до спільноти" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -12791,6 +12807,1372 @@ msgstr "" "мережі або підключіть MCP-сервер Everywhere, щоб досліджувати записаний " "трафік разом з агентом." +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "Спеціалізація моделей{ph0}Есе" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "Чи потрібна для зворотної розробки більша модель?" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "" +"Що реконструкція Touhou допомагає зрозуміти про універсальні й " +"спеціалізовані моделі та навчання на зворотному зв’язку від компілятора." + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Автор N0zoM1z0 · 13 жовтня 2026 р" + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "Перейти до змісту" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "" +"{ph0}Домашня сторінка{ph1} / {ph2}Блог{ph3} / Моделі та зворотне " +"проектування" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "Есе" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "Чи потрібна для зворотного проектування більша модель?" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Автор N0zoM1z0 · 13 жовтня 2026 р" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "Головне" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "" +"{ph0}Можливості моделі впливають на те, які гіпотези може запропонувати " +"агент штучного інтелекту.{ph1} Пізніші сесії вирішували проблеми, які " +"попередня робота залишила невирішеними." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "" +"{ph0}Знайомий компілятор пропонує конкретні шаблони для вивчення " +"спеціалізованої моделі.{ph1} Деякі точні збіги машинного коду залежать від " +"конкретних шаблонів вихідного коду, які можна багаторазово використовувати." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "" +"{ph0}Включіть знання репозиторію в справедливе порівняння.{ph1} Менша модель" +" із хорошим пошуком знань може вже мати достатньо інформації для прогресу." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "" +"{ph0}Навчіть модель вибирати наступний корисний експеримент і протестуйте її" +" засіб перевірки.{ph1} Зворотній зв’язок корисний лише в тій мірі, в якій " +"засіб перевірки перевіряє правильні речі." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "" +"{ph0}Оцінка перевірених результатів реконструкції разом із часом і " +"вартістю.{ph1} Це те, що я хочу виміряти для повного робочого процесу AI-" +"agent." + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "У цій статті" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}Що змінили сильніші моделі{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}Навіщо спеціалізуватися?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}Де зберігати цей досвід?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}Вивчення наступного корисного експерименту{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}Зворотне проектування та навчання з посиленням{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}Коли засіб перевірки помиляється{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}Варте порівняння{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}Що це за агент ШІ?{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "Що змінили сильніші моделі" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"З серпня 2026 року я досліджував, який обсяг зворотного проектування може " +"виконати агент, маючи доступ до програми та спосіб перевірки її роботи. " +"Більшість мого досвіду отримано від реконструкції ігор, особливо Touhou. " +"Оскільки я змінював моделі, репозиторії зберігали записи про те, що вдалося " +"відновити за кожну сесію." + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"Значна частина цієї роботи спрямована на точну реконструкцію: ми компілюємо " +"підтримуваний джерело в ланцюжку історичних інструментів із фіксованими " +"версіями та перевіряємо, чи він відтворює цільову функцію. Коли пізніша " +"модель досягає успіху там, де попередня робота зупинилася, зміни джерела " +"показують, що зробило цей прогрес можливим." + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "Тимчасові змінні потребували часу існування, що збігався" + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"Значна частина логіки функції атаки TH09 вже була реконструйована, але " +"компілятор усе ще зберігав тимчасові результати, відмінні від оригіналу. " +"Проблема, що залишилася, полягала в тому, як довго ці результати залишалися " +"живими та коли їхнє сховище можна було використовувати повторно." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"{ph0}GPT-6-Sol запис сеансу{ph1} повідомив про цю невідповідність після " +"тестування кількох звичайних механізмів вихідного коду. Коли " +"{ph2}GPT-6.1-Sol знову дослідив проблему{ph3}, він запропонував корисну " +"гіпотезу щодо тривалості життя цих тимчасових змінних." + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"Функція створила тимчасові результати та скопіювала їх у позиції анімації. У" +" C++ тимчасовий результат залишається активним до завершення виразу, який " +"його використовує. Групування реальних операцій в один вираз зберігало ці " +"результати разом, тому компілятор більше не міг повторно використовувати те " +"саме сховище для всіх них." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"Один результат все ще ділився пам’яттю зі значенням, яке використовується " +"пізніше для перевірок на конфлікти. Надання цьому значенню власного часу " +"життя вирішило решту накладання. Після кількох цілеспрямованих експериментів" +" {ph0}чиста повторна компіляція з джерела підтвердила, що повна функція " +"відповідає{ph1}." + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"Мені цікаво, як відкриття та випробування підтримували одне одного. Гіпотеза" +" про тривалість життя тимчасових об’єктів дала агенту ШІ новий напрямок. " +"Відгуки компілятора допомогли уточнити цю гіпотезу у вихідному коді, який " +"відповідав." + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "Інший графік потоку керування" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"Друга функція TH09 показує, чому цей новий напрямок може мати значення. Тут " +"перешкодою було те, що кілька філій поділилися своєю остаточною роботою. " +"Попередня робота {ph0}GPT-6.1-Sol{ph1} мала відповідні частини функції, але " +"гілки все одно з’єднувалися інакше, ніж у оригіналі." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}GPT-6-Astra змінив навколишній графік потоку керування{ph1}. Основні " +"шляхи тепер вели до спільного остаточного оновлення та повернення. У цій " +"вихідній структурі компілятор об’єднав гілки так само, як і в оригіналі. " +"Повна функція відповідала, і {ph2}окрема перевірка відновлення підтвердила " +"це{ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}Зміна подання відкрила більш продуктивний простір для пошуку.{ph1} " +"Обидва випадки дають мені підстави серйозно поставитися до загальної " +"можливості моделі: агент може довго пробувати місцеві варіації, перш ніж " +"знайти кращий спосіб вираження навколишньої роботи." + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"У той же час пізніші сеанси починалися з попередніх джерел і записаних " +"збоїв. Ця накопичена робота була частиною їхньої переваги. Історія дозволяє " +"нам ознайомитися з відкриттями та їх перевірками; контрольоване порівняння " +"допомогло б відокремити ефект моделі від досвіду, який вона успадкувала." + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"Ось що робить питання цікавим для мене. Певний прогрес став завдяки пошуку " +"нового представництва. Значна частина роботи, що залишилася, включала " +"тестування різних механізмів вихідного коду на знайомому компіляторі. " +"Наскільки для цього потрібна широка здатність міркувати? Скільки може " +"навчитися модель, постійно працюючи з цим компілятором і кодом?" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "Чому спеціалізована модель ШІ може працювати добре?" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"Touhou дає нам конкретну причину очікувати, що цей досвід допоможе. Значна " +"частина ігрового коду походить від того самого автора, ZUN, тому повторювані" +" звички є розумним вихідним припущенням. Репозиторії підтверджують це " +"корисними прикладами: пов’язані цикли та допоміжні механізми надають " +"гіпотези для різних ігор." + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "" +"Ці вихідні шаблони стають більш конкретними, коли ми включаємо компілятор. " +"За певної версії та набору параметрів невеликі зміни у джерелі можуть " +"призвести до повторюваних відмінностей у машинному коді. Деякі з цих " +"відмінностей напрочуд незрозумілі." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"У TH095, наприклад, {ph0}навіть ім’я локальної змінної могло вплинути на те," +" де VC7.1 її зберігати{ph1}. Переміщення його оголошення не вирішило макета " +"сховища. Однак більш рання фонова функція виявила шаблон іменування, який " +"вплинув на вибір компілятора. Це запропонувало більш перспективну гіпотезу " +"для {ph2}реконструкції {ph3}{ph4}." + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "" +"Повторне використання цього шаблону для змінної розміру файлу створило " +"необхідний макет без додавання пам’яті. Тоді повна функція збігалася." + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "" +"Це дуже конкретна деталь, яку модель ШІ загального призначення може не " +"знати, коли вперше стикається з проблемою. Спеціалізована модель для цього " +"компілятора може побачити багато таких випадків і дізнатися, які варіації " +"вихідного коду варто перевірити в першу чергу." + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"Можливість особливо чітка в остаточних задачах зіставлення, де ми вже " +"розуміємо поведінку. Тоді ми запитуємо, яку звичайну структуру вихідного " +"коду цей компілятор перетворює на спостережувані інструкції. Спеціалізація " +"може допомогти моделі запропонувати ці форми ефективніше, тоді як ціль все " +"ще визначає, які гіпотези виживуть." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"Корисні шаблони повинні зберігати свій контекст. TH08 використовує попередню" +" версію Visual C++, ніж TH095 і TH09. TH04 використовує компілятор, " +"відмінний від епохи DOS. Його {ph0}реконструкція коду гравця{ph1} " +"потребувала різних гіпотез щодо шаблонів вихідного коду та того, як " +"скомпільований код зв’язувався у виконуваний файл. Наявність того самого " +"автора дає нам початкове очікування, але кожна ціль говорить нам, чи вона " +"застосовна. Спеціалізована модель повинна розрізняти ці контексти." + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "Де зберігати цей досвід?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"Перш ніж вирішувати навчати цим шаблонам за допомогою моделювання, я б " +"подивився на знання, які ми вже зберігаємо в репозиторії. У " +"{ph0}попередньому есе{ph1} я писав про те, що це стало робочою пам’яттю " +"проекту. Ця пам’ять містить уроки компілятора, а також джерело та невдалі " +"експерименти, які зробили їх корисними." + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"Отримавши цей запис, агент може почати з відомого результату та перевірити, " +"як ми його досягли. Він також може уникнути альтернатив, які вже зазнали " +"невдачі в тому ж контексті. Початкова точка покращується без зміни навчених " +"параметрів моделі." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"Під час реконструкції функції TH09 для створення ворогів {ph0}GPT-6-Luna-max" +" сеанс{ph1} взяв гіпотезу з відповідного вихідного коду TH08. Цей попередній" +" код пропонував, як організувати цикл і обробляти збої в ньому. Власні " +"свідчення TH09 надали деталі гри. Перебудови з джерела підтвердили, що вся " +"функція відповідає." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}«Модель не знала про цю примху компілятора» та «модель не могла її " +"використати» — це різні проблеми.{ph1} Отримання може вирішити першу, але " +"для того, щоб перетворити цей факт на корисну кандидатуру, все ще потрібно " +"попрацювати. І якщо вихідний код кандидата зазнає невдачі, модель повинна " +"вирішити, що означає результат для її наступної спроби. Знання відповідного " +"шаблону – це лише початок цього процесу." + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"З цієї причини я б включив у будь-яке порівняння меншу модель ШІ загального " +"призначення з хорошим пошуком. Надання такої ж бібліотеки досвіду допомогло " +"б нам визначити, що додає навчання: краще формування кандидатів, кращі " +"рішення після зворотного зв’язку чи те й інше." + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "Вивчення наступного корисного експерименту" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"Я б найбільше хотів вивчити ці рішення після зворотного зв’язку. При " +"агентній реконструкції модель пропонує пояснення та перевіряє його на " +"програму. Навіть якщо вихідний код кандидата не вдається, результат може " +"звузити можливості, що залишилися, і запропонувати більш корисний наступний " +"експеримент." + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "" +"Знову розглянемо приклад із тимчасовими результатами. Його остаточне джерело" +" показує схему, яка спрацювала, але шлях до цього джерела містить більше " +"інформації. Кожен із наступних експериментів допоміг визначити, що ще " +"потрібно змінити." + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "Експериментуйте" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "Чого нас навчив його результат" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "Спробуйте інший спосіб скопіювати результати" + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "Код копіювання змінюється, але функція все ще відрізняється." + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "Використовуйте повернуті значення безпосередньо" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "" +"Копіювання відбувається за оригінальним шаблоном, але тимчасове зберігання " +"все ще відрізняється." + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "Зберігайте всі тимчасові змінні дійсними одночасно" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "" +"Вони отримують окреме сховище, але одне все одно перекриває значення, яке " +"буде використано пізніше для перевірок на конфлікти." + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "Зберігайте значення перевірки зіткнень окремо" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "Чиста перекомпіляція з джерела підтверджує повний збіг." + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "" +"Вибрані експерименти з наведеної вище реконструкції функції атаки, " +"згруповані за тим, чому вони нас навчили." + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"Навчальний запис, який зберігає цю послідовність, може навчити більше, ніж " +"одне лише кінцеве джерело. Він пов’язує кожну запропоновану зміну з " +"результатом спостереження та наступним рішенням. Збереження неефективних " +"варіацій також має значення: вони повідомляють пізнішому агенту, які " +"гіпотези вже були перевірені в цьому контексті." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}Я хотів би, щоб модель навчилася використовувати зворотній " +"зв’язок.{ph1} Нейтральний результат є причиною переглянути варіант; змінена " +"невідповідність може вказувати на іншу причину. Коли локальні редагування " +"перестають бути інформативними, агент повинен мати можливість переглянути " +"вихідне представлення або знову перевірити докази." + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"Щоб навчитися робити такий вибір, потрібна автономія. Іноді корисним " +"наступним кроком є ​​перевірка іншої функції, що викликає цю функцію, а не " +"компіляція іншого редагування. Жорстка послідовність необхідних переписів " +"усуне цей вибір разом із частиною поведінки, яку ми хочемо, щоб модель " +"навчила." + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "Чому зворотне проектування цікаве для навчання з підкріпленням" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"Реконструкція з визначеними межами дає практичне середовище для вивчення цих" +" рішень. Коли версії цілі й компілятора зафіксовані, багато експериментів із" +" вихідним кодом дають швидкий, відтворюваний зворотний зв’язок. Агент може " +"скомпілювати кандидата, перевірити відмінності та вибрати наступний крок." + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"Навчання з підкріпленням може тренувати цей процес прийняття рішень за " +"допомогою зворотного зв’язку, який він отримує. Кандидат, прийнятий за " +"певною перевіркою, дає нам конкретний результат, а послідовність спроб " +"дозволяє спостерігати, скільки роботи знадобилося для його досягнення." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"У цьому напрямку вже є дослідження. {ph0}LLM4Decompile{ph1} вивчає моделі, " +"що спеціалізуються на декомпіляції. {ph2}AutoDecompiler{ph3} тренує " +"багатоповоротне вдосконалення за допомогою компілятора та відгуків про " +"виконання. Їх дослідження зосереджені на функціональному відновленні. Для " +"цієї роботи я б використав їх як відправну точку для пов’язаного завдання " +"пошуку джерела, яке відповідає історичним результатам компілятора." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"Однак, щоб досягти такого чітко визначеного завдання, нам може спочатку " +"знадобитися встановити, якими ресурсами володіє функція, або розробити новий" +" спосіб спостереження за поведінкою програми під час виконання. У TH08, " +"наприклад, {ph0}різниця зіткнень призвела до того, як оригінальна програма " +"обробляла обчислення з плаваючою комою{ph1}. Перш ніж агент міг перевірити " +"корисну поправку, він повинен був визначити, що вимірювати." + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "" +"Це говорить про іншу роль широкофункціональної моделі: допомогти зробити " +"проблему перевіреною в першу чергу. Щойно така перевірка з’явиться, ми " +"зможемо дослідити, наскільки далеко може зайти вивчена політика пошуку з " +"нею." + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "Коли засіб перевірки помиляється" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"Коли перевірка використовується для навчання, її охоплення стає частиною " +"навчального середовища. Такий еталон або засіб перевірки я називаю оракулом." +" Навіть відтворювану відповідь потрібно розуміти в межах того, що вона " +"справді перевіряє." + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"TH08 показав, як багато можна приховати за межами цього покриття. Деякі " +"реконструйовані функції пройшли точне порівняння з неправильними плаваючими " +"константами. Компаратор скоригував переміщені адреси перед перевіркою " +"інструкцій, але він перевірив значення за цими адресами лише тоді, коли вони" +" були явно записані для перевірки. Інші літеральні посилання можуть пройти " +"без перевірки їхніх значень." + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"Щоб усунути цю прогалину, {ph0}ширший аудит{ph1} виявив неправильні " +"константи у функціях, які вже пройшли перевірку. В одному обчисленні " +"реконструйований вихідний код додав {ph2}, тоді як оригінальний додав {ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}Модель, нагороджена старою перевіркою перевірки, може навчитися " +"виробляти неправильну реконструкцію.{ph1} Ми не навчали модель RL за " +"допомогою цього засобу перевірки. Помилка, яку ми помітили, була в самій " +"перевірці. Але якби ми використовували це як винагороду, та сама сліпа пляма" +" стала б частиною навчального середовища." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"Функціональний тест може мати подібну сліпу пляму. {ph0}Дослідження з " +"використанням диференціального фаззингу на декомпіляторах LLM{ph1} виявили " +"поведінкові відмінності поза наданими тестами. Тому ми повинні розуміти " +"проходження тесту з точки зору випадків, які він виконує. Подібним чином " +"збіг інструкцій слід розуміти з точки зору байтів і даних, які він " +"перевіряє." + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"Перш ніж використовувати будь-який вид перевірки підтвердження як " +"винагороду, я б перевірив його з навмисно неправильними результатами. Я " +"також хотів би зберегти остаточне прийняття окремо від вихідного коду, який " +"агент ШІ може редагувати. Модель повинна пройти перевірку шляхом коректної " +"реконструкції програми. Інакше просте копіювання байтового масиву з " +"цільового об’єкта може обдурити наївну систему підрахунку балів без " +"відновлення корисного вихідного коду." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "" +"{ph0}Поліпшення моделі й поліпшення її засобу перевірки — частини однієї " +"дослідницької проблеми.{ph1} Що краще модель оптимізує наданий зворотний " +"зв’язок, то важливіше розуміти сам цей зв’язок." + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "Варте порівняння" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"За наявності цих перевірок я б почав порівняння з фіксованої сім’ї завдань " +"VC7.1. По-перше, я б визначив базові лінії для сильної моделі ШІ загального " +"призначення та меншої. Додавання знань про репозиторій до меншої моделі " +"покаже, які зміни в пошуку. Звідти контрольована спеціалізація та версія з " +"навчанням RL дозволять нам перевірити, що додає навчання." + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"Щоб зробити ці порівняння інформативними, кожна модель отримуватиме однакові" +" цільові дані та інструменти. Для порівнянь, пов’язаних із навчанням, я б " +"також залишив базову модель і наявні знання фіксованими. Повторні " +"випробування допомогли б відрізнити надійну стратегію пошуку від " +"альтернативного рішення, яке вдалось випадково." + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"Потім я б розділив дві початкові умови: реконструкція функції з її " +"інструкцій і закриття кількох останніх відмінностей у підтримуваному " +"джерелі. Спеціалізована модель штучного інтелекту може бути чудовою для " +"другого завдання, тоді як модель загального призначення виконує велику " +"частину роботи, необхідної для її досягнення. Вимірювання їх окремо виявило " +"б такий розподіл роботи." + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"Для обох завдань потрібні тестові приклади, яких немає ані в навчальних " +"даних, ані в матеріалах для пошуку. Пов’язані ігри Touhou мають спільний код" +" рушія. Якщо відкласти лише одну гру, майже однакові функції все одно можуть" +" потрапити до навчання. Я б натомість відкладав цілі групи спорідненого " +"вихідного коду й виключав їхні перевірені відповіді як із навчальних даних, " +"так і з бібліотеки пошуку." + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"Для цих прикладів результатом будуть повні, незалежно перевірені збіги. " +"Рівні бюджети для пропозицій кандидатів або спроб компіляції допоможуть " +"порівняти якість пошуку. Вимірювання загального часу та вартості, включаючи " +"компіляцію, покаже, чи забезпечує така якість ефективний робочий процес. " +"Витрати на навчання слід вимірювати окремо." + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"Обидва вимірювання мають значення. Дешева пропозиція може призвести до " +"дорогого робочого процесу, якщо це спричинить більше компіляцій, які не " +"надають корисної інформації. І навпаки, повільніша модель може бути " +"економнішою, якщо швидше знайде корисний експеримент. Порівняння повинно " +"включати ці витрати." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"Підрахунок прийнятих результатів також зберігає проміжний прогрес у " +"перспективі. Один TH09 {ph0}кандидат для повторного збереження{ph1} виглядав" +" багатообіцяючим, оскільки скомпільована функція мала очікуваний розмір, але" +" повне порівняння все одно виявило значні відмінності. Зміни в тому, як " +"компілятор впорядковує інструкції, також можуть створити враження, що " +"кандидат ближчий до цілі, не вирішуючи основної проблеми. Така діагностика " +"може керувати наступним експериментом, але я б перевірив будь-яку винагороду" +" за «наближення» до повної перевірки прийняття." + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"Мені було б цікаво побачити закономірності цих результатів. Якщо " +"спеціалізована модель штучного інтелекту добре справляється зі знайомим " +"сімейством компіляторів, чи збережеться ця перевага після зміни " +"інструментального ланцюжка? І коли обидві моделі штучного інтелекту мають " +"хороший пошук, скільки ще додає навчання? Відповіді допоможуть нам вирішити," +" де кожен тип моделі є найбільш корисним." + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "Що це за агент ШІ?" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"Якщо виявиться, що моделі допомагають на різних етапах, корисною " +"домовленістю може бути широкий агент із доступом до спеціалізованої моделі " +"ШІ. Коли завдання стає звичним пошуком компілятора, воно може запитати " +"спеціалізовану модель AI для кандидатів. Якщо результати перестають мати " +"сенс, ширший агент може повернутися до цільових доказів або дослідити саме " +"вимірювання." + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "" +"У такій домовленості спеціалізація стає інструментом, який агент може " +"вибрати під час розслідування. Агент зберігає свободу змінювати напрямок, що" +" уможливило попередні прориви." + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"Це природно випливає з промислових змін, які я описав у попередньому есе. " +"Можливість проводити багато інших експериментів змінює спосіб організації " +"роботи. Це також дає нам привід запитати, які рішення потребують широкого " +"оцінювання, а які покращуються через повторний досвід роботи з певним " +"ремеслом." + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"Наразі найсильніша універсальна модель заслужила місце в моєму робочому " +"процесі, розв’язавши проблеми, які раніше залишалися нерозв’язаними. Ці " +"успіхи спонукають мене дослідити процес: яка частина залежала від широти її " +"можливостей, а яку могла б виконати модель, навчена саме такої " +"реконструкції?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "" +"{ph0}Репозиторії дають нам спосіб перевірити запитання.{ph1} Я хотів би " +"використати цей запис для порівняння та побачити, що ми дізнаємося." + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "Докази та атрибуція моделі" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"Приклади описують історичні порівняння на рівні функцій, записані у " +"зв’язаних комітах. Перевірки виконання всієї гри є окремими етапами. Вихідні" +" та відповідні записи було переглянуто 13 жовтня 2026 року." + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"Мітка TH09 {ph0} означає GPT-6-Astra. Модель, пов’язана з {ph1}, змінювалася" +" з часом, тому лише ця мітка не може ідентифікувати модель, яка " +"використовується в певному циклі. Явні назви моделей в інших цитованих " +"комітах забезпечують записане присвоєння. Ці історії не містять узгоджених " +"вимірювань витрат або зусиль для кожного запуску." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "" +"{ph0}TH09 терміни життя тимчасових об’єктів:{ph1} {ph2}попередній перегляд " +"контексту{ph3} та {ph4}повна реконструкція, підтверджена чистою " +"перекомпіляцією з джерела{ph5}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"{ph0}TH09 Front зворотний виклик:{ph1} {ph2}діагностичні області, які не " +"збігаються{ph3}, {ph4}Astra новий графік потоку керування{ph5} та його " +"{ph6}перевірка прийнятої повторної компіляції{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}Знання компілятора:{ph1} {ph2}TH095 повторне використання поведінки " +"сегмента ідентифікатора{ph3}, {ph4}TH04 вихідний код гравця та порядок " +"зв’язування{ph5} та повна реконструкція {ph6}Luna функції створення ворогів " +"TH09{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}Перевірки та діагностика:{ph1} {ph2}TH08 постійний аудит із плаваючою " +"комою{ph3}, {ph4}TH08 числове дослідження{ph5} та {ph6}TH09 реконструкція зі" +" збереженням повтору{ph7}." + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "" +"Пропоновані порівняння спеціалізованих моделей і навчання RL є майбутніми " +"експериментами. Історії проекту мотивують їх. Жодна навчена спеціалізована " +"модель не оцінювалася для цього есе." + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "Чи потрібна для зворотного проектування більша модель? | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "" +"Чого навчила мене реконструкція Touhou щодо загальних моделей, спеціальних " +"моделей і навчання пропонувати кращі гіпотези на основі відгуків " +"компілятора." + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "На цій сторінці" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "Есе про моделі та зворотне проектування" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "Вибрані досліди реконструкції" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "Нагору" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "" +"{ph0}Докладні записи доказів{ph1} містять результати порівнянь і контекст " +"експериментів." + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "Автор: N0zoM1z0 · 13 жовтня 2026 р. · Чернетка для обговорення" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "Посібник зі встановлення" diff --git a/website/locales/vi/messages.po b/website/locales/vi/messages.po index d9dd57fb0..dac24ee02 100644 --- a/website/locales/vi/messages.po +++ b/website/locales/vi/messages.po @@ -32,18 +32,18 @@ msgid "Thoughts on reverse engineering." msgstr "Suy nghĩ về kỹ thuật đảo ngược." #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "Tái thiết trò chơi{ph0}Bài luận" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "Cuộc cách mạng công nghiệp trong kỹ thuật đảo ngược" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " @@ -52,19 +52,20 @@ msgstr "" "NHỮNG gì HƯỚNG DẪN SỬ DỤNG LẠI VÀ tái TẠO TH08, TH095 và TH04 đã dạy tôi về " "các agent, xác minh và kiến thức mà các hợp chất trong các dự án." -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "Đọc bài viết" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "Bởi N0zoM1z0 * 10 tháng mười 2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -100,6 +101,8 @@ msgstr "" "REA và AI." #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -136,6 +139,7 @@ msgstr "" "mã hóa của bạn." #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -156,6 +160,7 @@ msgid "REA home" msgstr "Trang chủ REA" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -176,6 +181,7 @@ msgid "Main navigation" msgstr "Điều hướng chính" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -196,6 +202,7 @@ msgid "REA on GitHub" msgstr "REA TRÊN GitHub" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -216,6 +223,7 @@ msgid "Join REA on Discord" msgstr "Tham gia Discord của REA" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -235,7 +243,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "Theo DÕI REA Trên X" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "Về đầu trang" @@ -11594,6 +11602,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "Khoảng cách tương tự: 256 ÷ 16 = 16 đơn vị góc = 22,5°" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -11614,6 +11623,7 @@ msgid "Showcases" msgstr "Ví dụ thực tế" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -11634,6 +11644,7 @@ msgid "Blog" msgstr "Blog" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -11654,6 +11665,7 @@ msgid "Get started" msgstr "Bắt đầu" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -11673,7 +11685,8 @@ msgctxt "shared" msgid "Guides" msgstr "Hướng dẫn" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -11693,7 +11706,8 @@ msgctxt "shared" msgid "Source" msgstr "Mã nguồn" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -11713,7 +11727,8 @@ msgctxt "shared" msgid "MIT license" msgstr "Giấy phép MIT" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -11733,7 +11748,8 @@ msgctxt "shared" msgid "Join the community" msgstr "Tham gia cộng đồng" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -12692,6 +12708,1372 @@ msgstr "" "1.2 để lấy Evidence từ bản ghi trong REA ngoại tuyến, hoặc kết nối máy chủ " "MCP của Everywhere để kiểm tra lưu lượng đã ghi cùng trợ lý của bạn." +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "Mô hình chuyên biệt{ph0}Bài viết" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "Kỹ thuật đảo ngược có cần mô hình lớn hơn không?" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "" +"Những suy nghĩ từ việc tái dựng Touhou về mô hình tổng quát, mô hình chuyên " +"biệt và cách học từ phản hồi của trình biên dịch." + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Bởi N0zoM1z0 · 13 tháng 10 năm 2026" + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "Bỏ qua nội dung" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "{ph0}Home{ph1} / {ph2}Blog{ph3} / Mô hình và kỹ thuật đảo ngược" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "Tiểu luận" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "Kỹ thuật đảo ngược có cần một mô hình lớn hơn không?" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "Bởi N0zoM1z0 · 13 tháng 10 năm 2026" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "Điểm chính" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "" +"{ph0}Khả năng của mô hình ảnh hưởng đến những giả thuyết mà tác nhân AI có " +"thể đề xuất.{ph1} Các phiên sau đã giải quyết các vấn đề mà công việc trước " +"đó chưa được giải quyết." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "" +"{ph0}Một trình biên dịch quen thuộc cung cấp các mẫu cụ thể để một mô hình " +"chuyên biệt học.{ph1} Một số kết quả khớp mã máy chính xác phụ thuộc vào các" +" mẫu mã nguồn cụ thể, có thể tái sử dụng." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "" +"{ph0}Bao gồm kiến thức kho lưu trữ trong một so sánh công bằng.{ph1} Một mô " +"hình nhỏ hơn với khả năng truy xuất kiến thức tốt có thể đã có đủ thông tin " +"để đạt được tiến bộ." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "" +"{ph0}Huấn luyện mô hình để chọn thử nghiệm hữu ích tiếp theo và kiểm tra " +"công cụ xác minh của nó.{ph1} Phản hồi chỉ hữu ích trong phạm vi công cụ xác" +" minh những điều đúng." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "" +"{ph0}Đánh giá kết quả tái thiết đã được xác minh cùng với thời gian và chi " +"phí.{ph1} Đó là những gì tôi muốn đo lường cho quy trình làm việc hoàn chỉnh" +" của tác nhân AI." + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "Trong bài viết này" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}Mô hình mạnh hơn đã thay đổi điều gì?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}Tại sao nên chuyên môn hóa?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}Kinh nghiệm này nên được lưu trữ ở đâu?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}Học thí nghiệm hữu ích tiếp theo{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}Học kỹ thuật đảo ngược và tăng cường{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}Khi công cụ xác minh sai{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}Một so sánh đáng chạy{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}Điều này gợi ý loại tác nhân AI nào?{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "Mô hình mạnh hơn đã thay đổi điều gì?" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"Kể từ tháng 8 năm 2026, tôi đã khám phá mức độ kỹ thuật đảo ngược mà một tác" +" nhân có thể thực hiện khi có quyền truy cập vào một chương trình và cách " +"kiểm tra công việc của nó. Phần lớn kinh nghiệm của tôi đến từ việc xây dựng" +" lại trò chơi, đặc biệt là Touhou. Khi tôi thay đổi mô hình, các kho lưu trữ" +" đã lưu giữ một bản ghi về những gì mỗi phiên đã khôi phục được." + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"Phần lớn công việc hướng tới tái dựng chính xác: biên dịch mã nguồn đang " +"được duy trì bằng chuỗi công cụ lịch sử có phiên bản cố định, rồi kiểm tra " +"xem nó có tái tạo hàm đích hay không. Khi mô hình sau giải quyết được điểm " +"mà công việc trước bị mắc kẹt, thay đổi trong mã nguồn cho thấy điều gì đã " +"giúp tiến triển." + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "Các biến tạm thời cần có thời gian tồn tại chồng chéo" + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"Phần lớn logic của hàm tấn công TH09 đã được xây dựng lại, nhưng trình biên " +"dịch vẫn lưu trữ các kết quả tạm thời khác với kết quả ban đầu. Vấn đề còn " +"lại là những kết quả đó cần tồn tại trong bao lâu và khi nào bộ nhớ của " +"chúng có thể được sử dụng lại." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"Bản ghi phiên {ph0}GPT-6-Sol{ph1} đã báo cáo sự không khớp này sau khi kiểm " +"tra một số cách sắp xếp mã nguồn thông thường. Khi {ph2}GPT-6.1-Sol kiểm tra" +" lại vấn đề{ph3}, nó đã đề xuất một giả thuyết hữu ích về thời gian tồn tại " +"của các biến tạm thời này." + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"Hàm này tạo ra các kết quả tạm thời và sao chép chúng vào các vị trí hoạt " +"ảnh. Trong C++, kết quả tạm thời vẫn tồn tại cho đến khi biểu thức sử dụng " +"nó kết thúc. Việc nhóm các hoạt động thực tế thành một biểu thức giúp giữ " +"cho các kết quả đó tồn tại cùng nhau, do đó trình biên dịch không thể sử " +"dụng lại cùng một bộ lưu trữ cho tất cả chúng nữa." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"Một kết quả vẫn được chia sẻ bộ nhớ với giá trị được sử dụng sau này để kiểm" +" tra xung đột. Việc đưa ra giá trị đó trong thời gian tồn tại của chính nó " +"đã giải quyết được sự chồng chéo còn lại. Sau một số thử nghiệm có mục tiêu," +" {ph0}việc biên dịch lại rõ ràng từ nguồn đã xác nhận rằng hàm đầy đủ khớp " +"với{ph1}." + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"Tôi quan tâm đến việc khám phá và thử nghiệm hỗ trợ lẫn nhau như thế nào. " +"Giả thuyết về thời gian tồn tại của đối tượng tạm thời đã mang lại cho tác " +"nhân AI một hướng đi mới. Phản hồi của trình biên dịch đã giúp nó tinh chỉnh" +" giả thuyết đó thành một cách sắp xếp mã nguồn phù hợp." + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "Biểu đồ luồng điều khiển khác" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"Hàm TH09 thứ hai cho biết tại sao hướng đi mới đó lại quan trọng. Ở đây, trở" +" ngại là làm thế nào một số chi nhánh chia sẻ công việc cuối cùng của họ. " +"Công việc trước đó của {ph0}GPT-6.1-Sol{ph1} có các phần của hàm khớp với " +"nhau, nhưng các nhánh vẫn được nối với nhau khác với ban đầu." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}GPT-6-Astra đã thay đổi biểu đồ luồng điều khiển xung quanh{ph1}. Các " +"đường dẫn chính hiện đã dẫn đến bản cập nhật cuối cùng được chia sẻ và quay " +"trở lại. Trong cấu trúc nguồn đó, trình biên dịch kết hợp các nhánh giống " +"như bản gốc. Chức năng hoàn chỉnh đã khớp và một cuộc kiểm tra xây dựng lại " +"riêng biệt {ph2} đã xác nhận điều đó{ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}Việc thay đổi cách biểu diễn đã mở ra một không gian tìm kiếm hiệu quả " +"hơn.{ph1} Cả hai trường hợp đều cho tôi lý do để xem xét nghiêm túc khả năng" +" của mô hình chung: một tác nhân có thể tiếp tục thử các biến thể cục bộ " +"trong một thời gian dài trước khi tìm ra cách tốt hơn để thể hiện công việc " +"xung quanh." + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"Đồng thời, các phiên sau bắt đầu với nguồn trước đó và ghi lại lỗi. Công " +"việc tích lũy đó là một phần lợi thế của họ. Lịch sử cho phép chúng ta kiểm " +"tra những khám phá và kiểm tra chúng; một so sánh có kiểm soát sẽ giúp tách " +"biệt tác động của mô hình khỏi trải nghiệm mà nó kế thừa." + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"Đây là điều làm cho câu hỏi trở nên thú vị đối với tôi. Một số tiến bộ đến " +"từ việc tìm kiếm một đại diện mới. Phần lớn công việc còn lại liên quan đến " +"việc kiểm tra các cách sắp xếp mã nguồn khác nhau dựa trên một trình biên " +"dịch quen thuộc. Bao nhiêu trong số này đòi hỏi khả năng suy luận rộng? Một " +"mô hình có thể học được bao nhiêu khi làm việc liên tục với trình biên dịch " +"và mã đó?" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "Tại sao một mô hình AI chuyên biệt có thể hoạt động tốt?" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"Touhou cho chúng ta lý do cụ thể để mong đợi trải nghiệm đó sẽ hữu ích. Phần" +" lớn mã trò chơi đều đến từ cùng một tác giả, ZUN, vì vậy những thói quen " +"lặp đi lặp lại là một giả định khởi đầu hợp lý. Các kho lưu trữ hỗ trợ điều " +"đó bằng các ví dụ hữu ích: các vòng lặp liên quan và cách sắp xếp trợ giúp " +"đã cung cấp các giả thuyết cho các trò chơi." + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "" +"Các mẫu nguồn đó trở nên cụ thể hơn khi chúng tôi đưa trình biên dịch vào. " +"Trong một phiên bản và tập hợp các tùy chọn cụ thể, những thay đổi nhỏ về " +"nguồn có thể tạo ra những khác biệt lặp lại trong mã máy. Một số trong những" +" khác biệt đó mơ hồ một cách đáng ngạc nhiên." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"Ví dụ: trong TH095, {ph0}ngay cả tên biến cục bộ cũng có thể ảnh hưởng đến " +"vị trí VC7.1 lưu trữ nó{ph1}. Việc di chuyển khai báo của nó không giải " +"quyết được bố cục lưu trữ. Tuy nhiên, hàm nền trước đó đã tiết lộ kiểu đặt " +"tên ảnh hưởng đến sự lựa chọn của trình biên dịch. Điều đó gợi ý một giả " +"thuyết hứa hẹn hơn cho việc {ph2}tái tạo {ph3}{ph4}." + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "" +"Việc sử dụng lại mẫu đó cho biến kích thước tệp sẽ tạo ra bố cục cần thiết " +"mà không cần thêm bộ nhớ. Các chức năng đầy đủ sau đó phù hợp." + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "" +"Đây là một chi tiết rất cụ thể mà một mô hình AI đa năng có thể không biết " +"khi lần đầu gặp sự cố. Một mô hình chuyên dụng cho trình biên dịch này có " +"thể xem nhiều trường hợp như vậy và tìm hiểu xem biến thể mã nguồn nào đáng " +"để thử nghiệm trước tiên." + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"Cơ hội đặc biệt rõ ràng trong các bài toán so khớp cuối cùng khi chúng ta đã" +" hiểu rõ hành vi. Sau đó, chúng tôi sẽ hỏi trình biên dịch này sẽ chuyển sự " +"sắp xếp mã nguồn thông thường nào thành các lệnh máy được quan sát. Sự " +"chuyên môn hóa có thể giúp mô hình đề xuất các hình thức đó hiệu quả hơn, " +"trong khi mục tiêu vẫn xác định giả thuyết nào tồn tại." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"Các mẫu hữu ích phải đi kèm bối cảnh áp dụng. TH08 dùng phiên bản Visual C++" +" cũ hơn TH095 và TH09. TH04 dùng một trình biên dịch khác thuộc thời DOS. " +"{ph0}Việc tái dựng mã điều khiển người chơi{ph1} cần những giả thuyết khác " +"về cách viết mã và cách liên kết thành tệp thực thi. Cùng tác giả là một giả" +" định ban đầu; từng mục tiêu cho biết giả định đó có phù hợp không. Mô hình " +"chuyên biệt cần học cách phân biệt các bối cảnh này." + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "Kinh nghiệm này nên được lưu trữ ở đâu?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"Trước khi quyết định dạy những mẫu đó thông qua đào tạo mô hình, tôi sẽ xem " +"xét kiến thức mà chúng tôi đã lưu giữ trong kho. Trong {ph0}bài luận " +"trước{ph1}, tôi đã viết về việc nó trở thành bộ nhớ làm việc của dự án. Bộ " +"nhớ đó bao gồm các bài học về trình biên dịch, cùng với nguồn và các thử " +"nghiệm thất bại khiến chúng trở nên hữu ích." + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"Bằng cách truy xuất bản ghi đó, nhân viên hỗ trợ có thể bắt đầu với kết quả " +"đã biết và kiểm tra cách chúng tôi đạt được kết quả đó. Nó cũng có thể tránh" +" được những lựa chọn thay thế đã thất bại trong cùng bối cảnh. Điểm bắt đầu " +"được cải thiện mà không thay đổi các tham số đã huấn luyện của mô hình." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"Trong khi xây dựng lại chức năng tạo kẻ thù của TH09, phiên {ph0}GPT-6-Luna-" +"max{ph1} đã lấy một giả thuyết từ mã nguồn TH08 có liên quan. Mã trước đó đã" +" đề xuất cách tổ chức vòng lặp và xử lý các lỗi bên trong nó. Bằng chứng " +"riêng của TH09 đã cung cấp chi tiết cụ thể về trò chơi. Việc xây dựng lại từ" +" nguồn đã xác nhận rằng toàn bộ hàm khớp với bản gốc." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}\"Mô hình không biết lỗi của trình biên dịch\" và \"mô hình không thể " +"sử dụng nó\" là các vấn đề khác nhau.{ph1} Việc truy xuất có thể giải quyết " +"được vấn đề đầu tiên, nhưng việc biến thực tế đó thành một mã ứng viên hữu " +"ích vẫn cần nhiều công sức. Và nếu mã nguồn mã ứng viên không thành công, mô" +" hình phải quyết định kết quả có ý nghĩa gì cho lần thử tiếp theo. Biết mẫu " +"có liên quan chỉ là bước khởi đầu của quá trình đó." + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"Vì lý do đó, tôi sẽ đưa vào một mô hình AI có mục đích chung nhỏ hơn với khả" +" năng truy xuất tốt trong mọi so sánh. Cung cấp cho nó cùng một thư viện " +"kinh nghiệm sẽ giúp chúng tôi xác định nội dung đào tạo bổ sung: tạo ứng " +"viên tốt hơn, đưa ra quyết định tốt hơn sau khi phản hồi hoặc cả hai." + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "Học thí nghiệm hữu ích tiếp theo" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"Những quyết định sau khi được phản hồi là điều tôi muốn nghiên cứu nhất. " +"Trong tái cấu trúc tác nhân, mô hình đề xuất một lời giải thích và kiểm tra " +"nó dựa trên chương trình. Ngay cả khi mã nguồn ứng viên không thành công, " +"kết quả có thể thu hẹp các khả năng còn lại và đề xuất thử nghiệm tiếp theo " +"hữu ích hơn." + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "" +"Hãy xem xét lại ví dụ về kết quả tạm thời. Nguồn cuối cùng của nó cho thấy " +"sự sắp xếp đã có hiệu quả nhưng đường dẫn đến nguồn đó chứa nhiều thông tin " +"hơn. Mỗi thử nghiệm sau đây đã giúp xác định những gì vẫn cần thay đổi." + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "Thử nghiệm" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "Kết quả của nó đã dạy chúng ta điều gì" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "Hãy thử một cách khác để sao chép kết quả" + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "Mã sao chép thay đổi nhưng chức năng vẫn khác." + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "Sử dụng trực tiếp các giá trị được trả về" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "Sao chép theo mẫu ban đầu, nhưng lưu trữ tạm thời vẫn khác." + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "Giữ tất cả các biến tạm thời hợp lệ cùng một lúc" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "" +"Chúng có bộ lưu trữ riêng biệt, nhưng một bộ vẫn chồng lên một giá trị được " +"sử dụng sau này để kiểm tra va chạm." + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "Giữ riêng giá trị kiểm tra va chạm" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "" +"Việc biên dịch lại rõ ràng từ nguồn xác nhận sự trùng khớp hoàn chỉnh." + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "" +"Các thử nghiệm được chọn từ quá trình tái cấu trúc chức năng tấn công ở " +"trên, được nhóm theo những gì chúng đã dạy chúng ta." + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"Một bản ghi huấn luyện lưu giữ trình tự này có thể dạy nhiều hơn chỉ riêng " +"nguồn cuối cùng. Nó kết nối từng thay đổi được đề xuất với kết quả được quan" +" sát và quyết định tiếp theo. Việc giữ lại các biến thể không hiệu quả cũng " +"rất quan trọng: chúng cho tác nhân sau này biết những giả thuyết nào đã được" +" kiểm tra trong bối cảnh đó." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}Tôi muốn mô hình học cách sử dụng phản hồi.{ph1} Kết quả trung lập là " +"lý do để xem xét lại biến thể; sự không phù hợp đã thay đổi có thể chỉ ra " +"một nguyên nhân khác. Khi các chỉnh sửa cục bộ không còn mang tính thông " +"tin, nhân viên sẽ có thể xem lại phần trình bày nguồn hoặc kiểm tra lại bằng" +" chứng." + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"Học cách đưa ra những lựa chọn đó đòi hỏi sự tự chủ. Đôi khi, bước tiếp theo" +" hữu ích là kiểm tra người gọi khác thay vì biên dịch một bản chỉnh sửa " +"khác. Một chuỗi các lần viết lại bắt buộc một cách cứng nhắc sẽ loại bỏ lựa " +"chọn đó, cùng với một phần hành vi mà chúng ta muốn mô hình học." + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "Tại sao kỹ thuật đảo ngược lại thú vị cho việc học tăng cường" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"Tái dựng trong phạm vi xác định là môi trường thực tế để nghiên cứu các lựa " +"chọn này. Khi phiên bản của mục tiêu và trình biên dịch được cố định, nhiều " +"thử nghiệm mã nguồn cho phản hồi nhanh và có thể lặp lại. Tác nhân có thể " +"biên dịch mã ứng viên, xem khác biệt rồi chọn bước tiếp theo." + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"Học tăng cường có thể rèn luyện quá trình ra quyết định đó thông qua phản " +"hồi mà nó nhận được. Một mã ứng viên được chấp nhận bởi một cuộc kiểm tra " +"xác định sẽ cho chúng ta một kết quả cụ thể, trong khi trình tự các lần thử " +"cho phép chúng ta quan sát xem cần bao nhiêu công sức để đạt được kết quả " +"đó." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"Đã có nghiên cứu hỗ trợ hướng này. {ph0}LLM4Decompile{ph1} nghiên cứu các mô" +" hình chuyên dùng cho việc dịch ngược. {ph2}AutoDecompiler{ph3} đào tạo sàng" +" lọc nhiều lượt bằng cách sử dụng phản hồi của trình biên dịch và thực thi. " +"Nghiên cứu của họ tập trung vào phục hồi chức năng. Đối với công việc này, " +"tôi sẽ sử dụng chúng làm điểm khởi đầu cho nhiệm vụ liên quan là tìm nguồn " +"phù hợp với đầu ra của trình biên dịch lịch sử." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"Tuy nhiên, để đạt được nhiệm vụ được xác định rõ ràng như vậy, trước tiên " +"chúng ta có thể cần thiết lập tài nguyên nào mà hàm sở hữu hoặc nghĩ ra cách" +" mới để quan sát hành vi của chương trình khi chạy. Ví dụ: trong TH08, sự " +"khác biệt về va chạm {ph0} dẫn đến cách chương trình ban đầu xử lý các phép " +"tính dấu phẩy động{ph1}. Trước khi tác nhân có thể kiểm tra một sự điều " +"chỉnh hữu ích, nó phải tìm ra những gì cần đo lường." + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "" +"Điều này gợi ý một vai trò khác của một mô hình có khả năng rộng rãi: giúp " +"làm cho vấn đề có thể được kiểm tra ngay từ đầu. Khi kiểm tra đó tồn tại, " +"chúng tôi có thể điều tra xem chính sách tìm kiếm đã học có thể đi được bao " +"xa." + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "Khi công cụ xác minh sai" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"Khi dùng một phép kiểm tra để huấn luyện, phạm vi kiểm tra cũng trở thành " +"một phần của môi trường học. Tôi gọi chuẩn tham chiếu hoặc công cụ kiểm tra " +"đó là oracle. Ngay cả câu trả lời lặp lại được cũng cần được hiểu theo những" +" gì nó thực sự xác minh." + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"TH08 cho thấy vấn đề có thể ẩn ngoài phạm vi kiểm tra. Một số hàm tái dựng " +"dùng hằng số dấu phẩy động sai nhưng vẫn vượt qua so sánh chính xác. Bộ so " +"sánh điều chỉnh địa chỉ tái định vị trước khi kiểm tra lệnh máy, nhưng chỉ " +"kiểm tra giá trị tại các địa chỉ đó nếu chúng đã được ghi nhận rõ ràng để " +"xác minh. Những tham chiếu hằng số khác có thể vượt qua mà không được kiểm " +"tra giá trị." + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"Để giải quyết khoảng trống này, {ph0}kiểm tra rộng hơn{ph1} đã tìm thấy các " +"hằng số không chính xác trong các hàm đã vượt qua quá trình xác minh. Trong " +"một phép tính, mã nguồn được xây dựng lại đã thêm {ph2}, trong khi mã nguồn " +"ban đầu được thêm {ph3}." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}Mô hình được khen thưởng bằng kiểm tra xác minh cũ có thể học cách tạo " +"ra bản dựng lại không chính xác.{ph1} Chúng tôi không đào tạo mô hình RL " +"bằng trình kiểm tra đó. Sự thất bại mà chúng tôi quan sát thấy nằm ở chính " +"việc kiểm tra. Nhưng nếu chúng ta sử dụng nó như một phần thưởng thì điểm mù" +" đó sẽ trở thành một phần của môi trường học tập." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"Một bài kiểm tra chức năng có thể có điểm mù tương tự. {ph0}Nghiên cứu sử " +"dụng tính năng làm mờ vi phân trên bộ giải mã LLM{ph1} đã tìm thấy những " +"khác biệt về hành vi bên ngoài các thử nghiệm được cung cấp. Do đó, chúng ta" +" cần hiểu một bài kiểm tra đạt theo các trường hợp mà nó thực hiện. Tương " +"tự, một lệnh khớp phải được hiểu theo byte và dữ liệu mà nó xác minh." + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"Trước khi sử dụng một trong hai loại kiểm tra xác minh làm phần thưởng, tôi " +"sẽ kiểm tra nó với kết quả cố tình sai. Tôi cũng sẽ tách biệt sự chấp nhận " +"cuối cùng với mã nguồn mà tác nhân AI có thể chỉnh sửa. Mô hình phải vượt " +"qua quá trình xác minh bằng cách xây dựng lại chương trình một cách chính " +"xác. Mặt khác, chỉ cần sao chép một mảng byte từ mục tiêu có thể đánh lừa " +"một hệ thống tính điểm ngây thơ mà không khôi phục được mã nguồn hữu ích." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "" +"{ph0}Cải thiện mô hình học và cải thiện công cụ xác minh là hai phần của " +"cùng một vấn đề nghiên cứu.{ph1} Mô hình càng giỏi tối ưu phản hồi được cung" +" cấp, chúng ta càng cần hiểu chính phản hồi đó." + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "Một so sánh đáng chạy" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"Với những bước kiểm tra đó, tôi sẽ bắt đầu so sánh trên nhóm nhiệm vụ VC7.1 " +"cố định. Đầu tiên, tôi sẽ thiết lập các đường cơ sở cho một mô hình AI có " +"mục đích chung mạnh mẽ và một mô hình nhỏ hơn. Việc bổ sung kiến ​​thức về " +"kho lưu trữ vào mô hình nhỏ hơn sẽ cho thấy những thay đổi trong quá trình " +"truy xuất. Từ đó, chuyên môn hóa được giám sát và phiên bản được đào tạo RL " +"sẽ cho phép chúng tôi kiểm tra nội dung đào tạo bổ sung." + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"Để làm cho những so sánh đó trở nên hữu ích, mỗi mô hình sẽ nhận được các " +"bằng chứng và công cụ mục tiêu giống nhau. Đối với các so sánh dành riêng " +"cho đào tạo, tôi cũng sẽ giữ nguyên mô hình cơ sở và kiến ​​thức có sẵn. Các" +" thử nghiệm lặp đi lặp lại sẽ giúp phân biệt một chiến lược tìm kiếm đáng " +"tin cậy với một giải pháp ứng viên tình cờ thành công." + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"Sau đó, tôi sẽ tách hai điều kiện bắt đầu: xây dựng lại một hàm từ các lệnh " +"máy của nó và đóng một số khác biệt cuối cùng trong nguồn được duy trì. Một " +"mô hình AI chuyên dụng có thể thực hiện xuất sắc nhiệm vụ thứ hai trong khi " +"một mô hình AI có mục đích chung thực hiện phần lớn công việc cần thiết để " +"đạt được nhiệm vụ đó. Việc đo lường chúng một cách riêng biệt sẽ tiết lộ sự " +"phân chia công việc đó." + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"Cả hai nhiệm vụ đều cần loại trừ các mẫu thử nghiệm khỏi quá trình đào tạo " +"và truy xuất. Trò chơi Touhou liên quan chia sẻ mã công cụ. Việc loại trừ " +"một trò chơi khỏi quá trình huấn luyện vẫn có thể để lại các chức năng gần " +"như giống hệt nhau trong tập huấn luyện. Thay vào đó, tôi sẽ loại trừ toàn " +"bộ các nhóm mã nguồn có liên quan và loại bỏ các câu trả lời đã được xác " +"minh của chúng khỏi cả dữ liệu huấn luyện và thư viện truy xuất." + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"Kết quả cần đo là các lần khớp hoàn chỉnh, được xác minh độc lập. Giới hạn " +"số mã ứng viên hoặc số lần biên dịch bằng nhau giúp so sánh chất lượng tìm " +"kiếm. Đo tổng thời gian và chi phí, kể cả biên dịch, cho biết chất lượng đó " +"có tạo ra quy trình hiệu quả không. Chi phí huấn luyện cần tính riêng." + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"Cả hai phép đo đều quan trọng. Một đề xuất rẻ tiền có thể dẫn đến một quy " +"trình làm việc tốn kém nếu nó tạo ra nhiều lần biên dịch không cung cấp " +"thông tin hữu ích. Ngược lại, một mô hình chậm hơn có thể tiết kiệm hơn nếu " +"nó tìm thấy một thử nghiệm hữu ích sớm hơn. Việc so sánh nên bao gồm những " +"chi phí này." + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"Việc đếm các kết quả được chấp nhận cũng giúp duy trì tiến độ trung gian. " +"Một TH09 {ph0}mã ứng viên lưu lại phát lại{ph1} có vẻ đầy hứa hẹn vì hàm " +"được biên dịch có kích thước như mong đợi nhưng so sánh đầy đủ vẫn tìm thấy " +"những khác biệt đáng kể. Những thay đổi trong cách trình biên dịch sắp xếp " +"các lệnh máy cũng có thể khiến mã ứng viên có vẻ gần hơn mà không giải quyết" +" được vấn đề cơ bản. Chẩn đoán như vậy có thể hướng dẫn thử nghiệm tiếp " +"theo, nhưng tôi sẽ xác thực bất kỳ phần thưởng nào cho việc \"tiến gần hơn\"" +" so với kiểm tra chấp nhận hoàn toàn." + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"Tôi sẽ quan tâm đến mô hình trên các kết quả này. Nếu một mô hình AI chuyên " +"dụng hoạt động tốt trong dòng trình biên dịch quen thuộc, liệu lợi thế đó có" +" tồn tại được khi thay đổi chuỗi công cụ không? Và một khi cả hai mô hình AI" +" đều có khả năng truy xuất tốt thì việc đào tạo vẫn bổ sung thêm bao nhiêu? " +"Câu trả lời sẽ giúp chúng ta quyết định xem mỗi loại mô hình sẽ hữu ích nhất" +" ở đâu." + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "Điều này gợi ý loại tác nhân AI nào?" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"Nếu các mô hình tỏ ra hữu ích ở các giai đoạn khác nhau, thì sự sắp xếp hữu " +"ích có thể là một tác nhân rộng rãi có quyền truy cập vào một mô hình AI " +"chuyên dụng. Khi một nhiệm vụ trở thành một công cụ tìm kiếm trình biên dịch" +" quen thuộc, nó có thể yêu cầu mô hình AI chuyên biệt dành cho ứng viên. Nếu" +" kết quả không còn có ý nghĩa nữa, tác nhân rộng hơn có thể quay lại bằng " +"chứng mục tiêu hoặc tự điều tra phép đo." + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "" +"Trong sự sắp xếp đó, sự chuyên môn hóa trở thành một công cụ mà đặc vụ có " +"thể lựa chọn khi cuộc điều tra phát triển. Người đại diện có quyền tự do " +"thay đổi hướng đi để có thể đạt được những đột phá trước đó." + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"Điều này diễn ra một cách tự nhiên từ sự chuyển dịch công nghiệp mà tôi đã " +"mô tả trong bài viết trước. Việc có thể chạy nhiều thử nghiệm hơn sẽ thay " +"đổi cách chúng ta tổ chức công việc. Nó cũng cho chúng ta lý do để hỏi những" +" quyết định nào cần được đánh giá rộng rãi và quyết định nào được cải thiện " +"thông qua kinh nghiệm lặp đi lặp lại với một nghề cụ thể." + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"Hiện tại, mô hình tổng quát mạnh nhất đã có chỗ đứng trong quy trình của tôi" +" vì giải quyết được những vấn đề trước đó còn bỏ ngỏ. Những thành công này " +"khiến tôi muốn xem kỹ quá trình: bao nhiêu phần phụ thuộc vào năng lực rộng " +"của mô hình, và bao nhiêu phần có thể giao cho một mô hình được huấn luyện " +"riêng cho kiểu tái dựng này?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "" +"{ph0}Các kho lưu trữ cung cấp cho chúng tôi một cách để kiểm tra câu " +"hỏi.{ph1} Tôi muốn sử dụng hồ sơ đó để xây dựng sự so sánh và xem những gì " +"chúng tôi học được." + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "Bằng chứng và quy kết mô hình" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"Các ví dụ mô tả các so sánh cấp độ chức năng lịch sử được ghi lại trong các " +"cam kết được liên kết. Kiểm tra thời gian chạy toàn bộ trò chơi là các cột " +"mốc riêng biệt. Nguồn và hồ sơ trùng khớp đã được xem xét vào ngày 13 tháng " +"10 năm 2026." + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"Nhãn TH09 {ph0} có nghĩa là GPT-6-Astra. Mô hình được liên kết với {ph1} đã " +"thay đổi theo thời gian, do đó, riêng nhãn đó không thể xác định được mô " +"hình được sử dụng trong một lần chạy cụ thể. Tên mô hình rõ ràng trong các " +"cam kết được trích dẫn khác cung cấp thông tin ghi nhận. Những lịch sử này " +"không bao gồm các phép đo nhất quán về chi phí hoặc nỗ lực cho mỗi lần chạy." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "" +"{ph0}TH09 thời gian tồn tại của đối tượng tạm thời:{ph1} {ph2}xem xét ngữ " +"cảnh trước đó{ph3} và {ph4} việc xây dựng lại hoàn chỉnh được xác minh bằng " +"cách biên dịch lại rõ ràng từ nguồn{ph5}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"{ph0}Callback Front của TH09:{ph1} {ph2}các vùng chẩn đoán chưa khớp{ph3}, " +"{ph4}đồ thị luồng điều khiển mới của Astra{ph5} và {ph6}phép kiểm tra biên " +"dịch lại đã được chấp nhận{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}Kiến thức về trình biên dịch:{ph1} {ph2}TH095 tái sử dụng hành vi của " +"nhóm nhận dạng{ph3}, {ph4}TH04 mã nguồn người chơi và thứ tự trình liên " +"kết{ph5} và {ph6}Luna tái thiết hoàn toàn chức năng tạo kẻ thù của " +"TH09{ph7}." + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}Kiểm tra và chẩn đoán:{ph1} {ph2}kiểm tra hằng số dấu phẩy động của " +"TH08{ph3}, {ph4}điều tra số học của TH08{ph5} và {ph6}tái dựng chức năng lưu" +" replay của TH09{ph7}." + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "" +"Những so sánh được đề xuất giữa các mô hình chuyên dụng và chương trình đào " +"tạo RL là những thử nghiệm trong tương lai. Lịch sử dự án thúc đẩy họ. Không" +" có mô hình chuyên ngành được đào tạo nào được đánh giá cho bài tiểu luận " +"này." + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "Kỹ thuật đảo ngược có cần một mô hình lớn hơn không? | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "" +"Việc tái xây dựng Touhou đã dạy tôi điều gì về các mô hình chung, mô hình " +"chuyên biệt và việc học cách đề xuất các giả thuyết tốt hơn từ phản hồi của " +"trình biên dịch." + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "Trên trang này" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "Mô hình và tiểu luận kỹ thuật đảo ngược" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "Các thí nghiệm tái thiết được chọn" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "Về đầu trang" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "" +"{ph0}Ghi chú bằng chứng chi tiết{ph1} bao gồm các kết quả so sánh và bối " +"cảnh thử nghiệm." + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "N0zoM1z0 · 13 tháng 10 năm 2026 · Bản nháp để góp ý" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "Hướng dẫn cài đặt" diff --git a/website/locales/zh-CN/messages.po b/website/locales/zh-CN/messages.po index 91728965c..9a4933ad7 100644 --- a/website/locales/zh-CN/messages.po +++ b/website/locales/zh-CN/messages.po @@ -32,37 +32,38 @@ msgid "Thoughts on reverse engineering." msgstr "逆向工程的思考。" #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "游戏重建{ph0}论文" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "逆向工程的工业革命" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " "agents, verification and knowledge that compounds across projects." msgstr "什么手动重新和重建TH08,TH095和TH04教我关于编程助手,验证和知识,跨项目的化合物。" -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "阅读文章" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "通过N0zoM1z0*10十月2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -96,6 +97,8 @@ msgid "" msgstr "对逆向工程的思考,借鉴与 REA 和AI编程助手。" #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -130,6 +133,7 @@ msgid "" msgstr "REA-了解软件的工作原理。 逆向工程与你的编程助手." #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -150,6 +154,7 @@ msgid "REA home" msgstr "REA 首页" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -170,6 +175,7 @@ msgid "Main navigation" msgstr "主导航" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -190,6 +196,7 @@ msgid "REA on GitHub" msgstr "在 GitHub 查看 REA" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -210,6 +217,7 @@ msgid "Join REA on Discord" msgstr "加入 REA 的 Discord 社区" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -229,7 +237,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "在 X 上关注 REA" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "回到顶部" @@ -10615,6 +10623,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "相同间距:256÷16=16角度单位=22.5°" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -10635,6 +10644,7 @@ msgid "Showcases" msgstr "案例展示" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -10655,6 +10665,7 @@ msgid "Blog" msgstr "博客" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -10675,6 +10686,7 @@ msgid "Get started" msgstr "开始使用" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -10694,7 +10706,8 @@ msgctxt "shared" msgid "Guides" msgstr "指南" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -10714,7 +10727,8 @@ msgctxt "shared" msgid "Source" msgstr "源代码" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -10734,7 +10748,8 @@ msgctxt "shared" msgid "MIT license" msgstr "MIT 许可证" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -10754,7 +10769,8 @@ msgctxt "shared" msgid "Join the community" msgstr "加入社区" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -11681,6 +11697,1146 @@ msgstr "" "要检查 HTTP 请求和响应正文,请使用{ph0}Fiddler Everywhere:SAZ 捕获、MCP 和公开技能{ph1}。导出 SAZ ? " "HAR 1.2 可在 REA 中离线获取捕获 Evidence,也可以连接 Everywhere 的 MCP 服务器,让智能体检查已捕获的流量。" +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "专用模型{ph0}随笔" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "逆向工程需要更大的模型吗?" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "从 Touhou 重建的经验,探讨通用模型、专用模型,以及如何从编译器反馈中学习。" + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "作者 N0zoM1z0 · 2026 年 10 月 13 日" + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "跳转到内容" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "{ph0}首页{ph1} / {ph2}博客{ph3} / 模型与逆向工程" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "随笔" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "逆向工程需要更大的模型吗?" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "作者 N0zoM1z0 · 2026 年 10 月 13 日" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "要点" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "{ph0}模型能力会影响 agent 能提出哪些假设。{ph1} 后来的工作解决了早期尝试未能解决的问题。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "{ph0}熟悉的编译器为专用模型提供了具体的学习对象。{ph1} 有些精确匹配依赖细小但可以复用的源码模式。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "{ph0}也要公平评估代码仓库里的知识。{ph1} 较小的模型配合良好的检索,可能已经掌握了足以推进工作的知识。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "{ph0}训练模型选择下一个有价值的实验,同时检验它使用的验证器。{ph1} 反馈是否有用,取决于验证器究竟检查了什么。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "{ph0}结合时间和成本,评估通过验证的重建成果。{ph1} 这是我希望从整个 agent 工作流中获得的结果。" + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "在本文中" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}更强的模型改变了什么{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}为什么考虑专用模型?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}这些经验应该存在哪里?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}学习选择下一个有价值的实验{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}逆向工程与强化学习{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}当验证器出错时{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}值得做的对照实验{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}这意味着怎样的 agent?{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "更强的模型改变了什么" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"从 2026 年 8 月开始,我一直在探索:如果给 agent " +"访问程序的能力,以及验证自身工作的手段,它能独立完成多少逆向工作?我的经验主要来自游戏重建,尤其是东方系列。随着我更换模型,代码仓库记录了每次工作还原出的内容。" + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"这些工作很大一部分追求精确重建:用固定版本的历史工具链编译我们维护的源码,检查它能否复现目标函数。当后来的模型解决了早期工作卡住的问题,我们可以从源码变化中看出,是什么促成了这次进展。" + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "临时值需要同时保持有效" + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"TH09 " +"中一个攻击函数的大部分逻辑已经还原,但编译器对临时结果的存储安排仍然与原版不同。剩下的问题在于:这些结果的生命周期应该多长,编译器何时可以复用它们的存储空间?" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"{ph0}GPT-6-Sol 的一次工作记录{ph1}表明,尝试几种常见的源码写法后,差异仍未消除。后来,{ph2}GPT-6.1-Sol " +"重新研究这个问题{ph3},提出了一个有价值的假设:关键可能在于这些临时值的生命周期。" + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"这个函数会产生临时结果,再把它们复制到动画的位置数据中。在 C++ " +"中,临时结果会一直存在,直到使用它的表达式执行完毕。把实际操作放进同一个表达式,就能让这些结果同时存活,编译器也就不能为它们全部复用同一块存储空间。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"其中一个结果仍然与稍后用于碰撞检查的值共享存储。给那个值单独的生命周期后,最后一处重叠也消失了。经过几次有针对性的实验,{ph0}一次干净的重新构建确认,整个函数都已匹配{ph1}。" + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"我感兴趣的是,发现与验证如何共同推进工作。生命周期的假设给 agent 指明了新方向;编译器的反馈又帮助它逐步调整源码,直到找到匹配的写法。" + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "换一种控制流结构" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"TH09 的另一个函数说明了,新方向为什么重要。这次的难点是多个分支如何共享末尾的操作。{ph0}GPT-6.1-Sol " +"之前的工作{ph1}已经让函数的一些部分匹配,但分支汇合的方式仍与原版不同。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}GPT-6-Astra " +"改写了外围的控制流图{ph1},让主要路径汇入共同的最终更新与返回。在这种源码结构下,编译器合并分支的方式与原版一致。整个函数实现了匹配,{ph2}另一次独立的重新构建也确认了这一结果{ph3}。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}换一种表达方式,打开了更有价值的搜索空间。{ph1} 这两个例子让我认真看待通用模型的能力:agent " +"可能花很长时间尝试局部变化,才找到一种更好的整体写法。" + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"不过,后来的工作也继承了之前的源码和失败记录。这些积累本身就是优势的一部分。历史记录让我们可以检查发现及其验证过程;要区分模型能力和继承经验各自带来的帮助,还需要对照实验。" + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"这正是我觉得有趣的地方。有些进展来自新的表达方式,剩下的大量工作则是在熟悉的编译器上试验不同写法。其中有多少需要广泛的推理能力?又有多少可以通过反复接触这个编译器和这些代码来学会?" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "为什么专用模型可能做得很好?" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"东方系列给了我们一个具体的理由,去期待经验积累能发挥作用。大量游戏代码出自同一个作者 " +"ZUN,因此,把反复出现的编程习惯作为初始假设是合理的。代码仓库也提供了实际例子:相似的循环和辅助函数组织方式,曾为其他游戏的重建提供假设。" + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "把编译器也考虑进去,这些源码模式就更加具体了。在固定版本和选项下,源码的小变化可能稳定地产生不同的机器码。其中一些规律藏得很深。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"以 TH095 为例,{ph0}连局部变量的名字,都可能改变 VC7.1 " +"为它安排的存储位置{ph1}。只移动声明并不能解决布局问题,但先前重建的一个背景函数揭示了会影响编译器选择的命名模式。这为{ph2}重建 " +"{ph3}{ph4}提供了更有希望的假设。" + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "把这个模式用于表示文件大小的变量,不增加额外存储就得到了所需布局。随后,整个函数实现了匹配。" + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "这类细节非常具体,通用模型第一次接触时未必知道。而针对这个编译器训练的专用模型,可以接触许多类似案例,学会哪些源码变化值得优先尝试。" + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"当我们已经理解函数行为,只剩最后的匹配差异时,这个机会尤其明显。此时的问题是:这个编译器会把哪一种普通写法编译成眼前的指令?专用训练可能让模型更高效地提出这些写法,而最终由目标程序决定哪些假设成立。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"但这些模式必须保留适用的上下文。TH08 使用的 Visual C++ 版本早于 TH095 和 TH09。TH04 用的是另一种 DOS " +"时代的编译器,其{ph0}玩家逻辑重建{ph1}需要不同的假设,既涉及源码写法,也涉及编译后的代码如何链接成可执行文件。同一作者为我们提供了先验,具体目标则告诉我们它是否适用。区分这些情况,也是专用模型需要学会的事。" + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "这些经验应该存在哪里?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"在决定通过训练让模型学会这些模式之前,我会先看看代码仓库里已有的知识。在{ph0}上一篇文章{ph1}中,我写过:仓库正在成为项目的工作记忆。这里保存着对编译器的认识,也保存着相关源码和失败实验,让这些经验有据可查。" + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"检索这些记录后,agent 可以从已知结果出发,看看我们是如何得到它的,也可以避开在相同条件下已经失败的方案。模型的参数没有改变,工作的起点却提高了。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"重建 TH09 的敌人生成函数时,{ph0}GPT-6-Luna-max 的一次工作{ph1}从 TH08 " +"对应的源码中找到了假设。之前的写法提示了循环该如何组织,以及内部失败该如何处理。TH09 " +"自身的证据补上了游戏特有的细节,干净的重新构建确认了整个函数的匹配。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}“模型不知道这个编译器特性”和“模型不会利用它”,是两个不同的问题。{ph1} " +"检索可能解决前者,但把知识变成有价值的候选源码,仍然需要能力。如果候选方案失败了,模型还得判断这次结果对下一次尝试意味着什么。知道相关模式,只是这个过程的起点。" + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"所以,在任何对照实验中,我都会加入一个具备良好检索能力的小型通用模型。给它相同的经验库,才能看清训练究竟增加了什么:更好的候选方案、更好的反馈后决策,还是两者都有?" + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "学习选择下一个有价值的实验" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"反馈之后如何决策,是我最想研究的部分。在 agent " +"驱动的重建中,模型提出解释,再用程序来验证。即使候选方案失败了,结果也可能缩小剩余的可能性,提示下一步更值得尝试什么。" + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "再看前面的临时结果例子。最终源码展示了成功的写法,但得到它的过程包含更多信息。下面的每次实验,都帮助我们确定了还有什么需要改变。" + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "实验" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "结果告诉了我们什么" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "尝试另一种复制结果的方式" + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "复制代码改变了,但函数仍有差异。" + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "直接使用返回值" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "复制方式与原版一致,但临时存储布局仍有差异。" + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "让临时结果同时保持有效" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "它们得到了各自的存储空间,但其中一个仍与稍后用于碰撞检查的值重叠。" + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "让碰撞检查的值拥有独立存储" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "干净的重新构建确认了整个函数的匹配。" + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "选自前面攻击函数的重建实验,按每次得到的认识整理。" + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"保存这个过程的训练记录,比单独保存最终源码能教会模型更多东西。它把每个改动、观察到的结果和下一步决策联系起来。无效的尝试也值得保留:后来的 agent " +"可以据此知道,在这个上下文中,哪些假设已经检验过。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}我希望模型学会如何利用反馈。{ph1} " +"结果没有变化,可能意味着该重新考虑这个改动;差异发生变化,则可能指向另一个原因。当局部修改不再提供有效信息时,agent " +"应该可以重新考虑源码的整体表达,或者回头检查证据。" + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"学会这些选择,需要自主性。有时,更有价值的下一步是检查另一个调用者,而不是再修改一次源码并编译。如果强制按照固定顺序改写,就会剥夺这种选择,也失去一部分我们希望模型学会的行为。" + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "为什么逆向工程值得用来探索强化学习" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"范围明确的重建任务,为研究这些选择提供了一个实际环境。目标和编译器版本固定之后,许多源码实验都能快速给出可重复的反馈。agent " +"可以编译候选源码、检查差异,再根据观察选择下一步。" + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"强化学习可以利用这些反馈,训练模型的决策过程。候选源码通过明确定义的检查,就给出了一个具体成果;而尝试的过程,让我们可以看到实现它花了多少功夫。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"已有研究支持这个方向。{ph0}LLM4Decompile{ph1}研究专门用于反编译的模型。{ph2}AutoDecompiler{ph3}利用编译和执行反馈,训练多轮改进能力。这些研究关注的是功能还原。对于我们的工作,我会以它们为起点,研究一个相关任务:找到能复现历史编译器输出的源码。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"不过,要得到这样一个定义明确的任务,有时得先确定函数负责哪些资源,或者设计新的方法观察程序运行时的行为。在 TH08 " +"中,{ph0}一次碰撞差异最终追溯到原版处理浮点计算的方式{ph1}。agent 必须先弄清楚该测量什么,才能验证有价值的修正。" + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "这提示了能力全面的模型的另一个作用:先把问题变得可验证。验证手段建立起来后,我们才可以研究,学出来的搜索策略能走多远。" + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "当验证器出错时" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"一旦用某项检查来训练模型,它的覆盖范围就会成为学习环境的一部分。我把这种参考标准或验证器称为 " +"oracle。即使它能给出可重复的答案,我们也必须知道,这个答案覆盖了什么。" + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"TH08 " +"展示了检查范围之外可能藏着多少问题。一些重建函数使用了错误的浮点常量,却仍然通过了精确比较。比较器会先调整重定位地址,再检查指令;但只有明确登记过的常量,才会进一步检查地址指向的值。其他常量引用,即使值没被检查,也可能通过。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"为了补上这个漏洞,{ph0}一次更全面的审计{ph1}在已经通过检查的函数中找到了错误常量。有一个计算中,重建源码加的是 {ph2},而原版加的是 " +"{ph3}。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}如果用旧检查的结果作为奖励,模型可能学会生成错误的重建源码。{ph1} 我们没有用这个验证器训练 RL " +"模型;实际观察到的是检查本身的漏洞。但如果把它用作奖励,同一个盲点也会进入学习环境。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"功能测试也可能存在类似盲点。{ph0}针对 LLM " +"反编译器的差分模糊测试研究{ph1}发现,在已有测试之外,程序行为仍可能不同。因此,理解“测试通过”时,必须看它实际覆盖了哪些情况;理解“指令匹配”时,也必须看它检查了哪些字节和数据。" + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"在把任何一种检查用作奖励之前,我都会用刻意构造的错误来测试它。我还会把最终验收机制放在候选源码可修改的范围之外,让模型通过正确重建来满足检查。否则,直接复制目标程序的字节数组,也可能骗过简单的评分,却没有还原出有用的源码。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "{ph0}改进模型和改进它的验证器,属于同一个研究问题。{ph1} 模型越擅长优化我们给它的反馈,我们就越需要理解反馈本身。" + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "值得做的对照实验" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"具备这些检查之后,我会从一组固定的 VC7.1 " +"任务开始比较。先为强通用模型和小型通用模型建立基线,再给小模型加入仓库知识,观察检索带来的变化。接着比较监督训练的专用模型,以及在此基础上进行 RL " +"训练的版本,看看训练增加了什么。" + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"为了让比较有意义,每个模型都应获得相同的目标证据和工具。专门比较训练效果时,还要固定基础模型和可用知识。重复实验有助于区分可靠的搜索策略与偶然成功的候选方案。" + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"我还会区分两种起点:从指令开始重建函数,以及在已有源码中消除最后几处差异。专用模型可能很擅长后者,而通用模型承担了到达这个阶段的大部分工作。分别评估,才能看清这种分工。" + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"两类任务都需要真正未见过的测试案例。东方系列的相关游戏会共享引擎代码,只留出某个游戏,仍可能让几乎相同的函数进入训练集。我会改为按相关源码家族留出测试集,并把它们通过验证的答案同时排除在训练数据和检索库之外。" + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"在这些案例上,要统计的是完整、独立验证过的匹配成果。给每个模型相同的候选数量或编译次数预算,可以比较搜索质量。记录总耗时和总成本,包括编译,才能知道这种质量是否转化成了高效的工作流。训练成本也要单独计算。" + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"两种角度都重要。一个便宜的提议,如果导致大量无效编译,整个工作流仍可能很贵。反过来,较慢的模型如果更早找到有价值的实验,也可能更划算。对照实验应当反映这些成本。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"只统计通过验收的结果,也能帮助我们合理看待中间进展。TH09 " +"的一个{ph0}录像保存候选方案{ph1}看起来很有希望,因为编译后函数的大小符合预期,但完整比较仍发现大量差异。编译器改变指令排列,也可能让候选源码看起来更接近,却没有解决根本问题。这些诊断可以指导下一步,但若要奖励“变得更接近”,我会先对照完整验收检查,确认这种奖励有效。" + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"我想看这些结果呈现出什么规律。如果专用模型在熟悉的编译器上表现很好,换了工具链后,这种优势还在吗?当双方都拥有良好的检索能力时,训练还能增加多少价值?这些答案能帮助我们决定,每类模型最适合用在哪里。" + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "这意味着怎样的 agent?" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"如果不同模型在不同阶段各有所长,一种有价值的安排可能是:让能力全面的 agent " +"可以调用专用模型。当任务变成一种熟悉的编译器搜索时,它可以请专用模型提出候选方案。如果结果开始说不通,通用 agent " +"可以回头检查目标证据,或者调查测量本身。" + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "" +"在这样的安排中,专用模型成为 agent 随着调查进展可以选择的工具。agent 仍然拥有改变方向的自由,而这正是前面那些突破发生的重要条件。" + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"这自然延续了上一篇文章中谈到的工业化转变。能够开展更多实验,会改变我们组织工作的方式,也让我们有理由追问:哪些决策需要全面的判断,哪些可以通过反复积累某项具体技艺来改善?" + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"目前,最强的通用模型解决了我过去没能解决的问题,因此在我的工作流中占据了一席之地。正是这些成功,让我想更仔细地研究过程:有多少依赖模型能力的广度?又有多少可以交给专门学习这类重建的模型?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "{ph0}这些代码仓库让我们有机会验证这个问题。{ph1} 我想利用这些记录建立对照实验,看看我们能学到什么。" + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "证据与模型归属" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"这些例子来自链接提交中记录的历史函数级比较。整款游戏的运行时检查属于另一个里程碑。相关源码与匹配记录核查于 2026 年 10 月 13 日。" + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"TH09 中的标签 {ph0} 对应 GPT-6-Astra。{ph1} " +"会随当时使用的模型变化,因此仅凭这个标签无法确定某次运行的具体模型。其他引用提交中的明确模型名,提供了对应的归属记录;这些历史记录并没有统一的单次运行成本或投入统计。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "{ph0}TH09 临时值生命周期:{ph1}{ph2}早期上下文检查{ph3}与{ph4}完整的干净重建{ph5}。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"{ph0}TH09 Front 回调:{ph1}{ph2}未匹配的诊断区域{ph3}、{ph4}Astra " +"提出的新控制流图{ph5}与{ph6}通过验收的重新编译检查{ph7}。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}编译器知识:{ph1}{ph2}TH095 标识符分桶规律的复用{ph3}、{ph4}TH04 " +"玩家源码与链接顺序{ph5}、{ph6}Luna 完成的 TH09 敌人生成函数匹配{ph7}。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}检查与诊断:{ph1}{ph2}TH08 浮点常量审计{ph3}、{ph4}TH08 数值问题调查{ph5}、{ph6}TH09 " +"录像保存重建{ph7}。" + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "文中提出的专用模型与 RL 对照,属于未来实验。项目历史为这些想法提供了依据;本文尚未评估经过训练的专用模型。" + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "逆向工程需要更大的模型吗? | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "东方重建让我如何思考通用模型、专用模型,以及怎样从编译器反馈中学会提出更好的假设。" + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "在本页" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "模型与逆向工程随笔" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "重建实验选例" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "回到顶部" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "{ph0}详细证据记录{ph1}包含历史比较结果与实验背景。" + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "作者 N0zoM1z0 · 2026 年 10 月 13 日 · 待审草稿" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "安装指南" diff --git a/website/locales/zh-TW/messages.po b/website/locales/zh-TW/messages.po index 875779f14..af7b68bcd 100644 --- a/website/locales/zh-TW/messages.po +++ b/website/locales/zh-TW/messages.po @@ -32,37 +32,38 @@ msgid "Thoughts on reverse engineering." msgstr "逆向工程的思考。" #. {ph0}:
-#: website/public/blog/index.html:200 +#: website/public/blog/index.html:214 #, python-brace-format msgctxt "page:blog/index.html" msgid "Game reconstruction{ph0}Essay" msgstr "遊戲重建{ph0}論文" -#: website/public/blog/index.html:202 +#: website/public/blog/index.html:216 msgctxt "page:blog/index.html" msgid "The industrial revolution in reverse engineering" msgstr "逆向工程的工業革命" -#: website/public/blog/index.html:203 +#: website/public/blog/index.html:217 msgctxt "page:blog/index.html" msgid "" "What manual RE and reconstructing TH08, TH095 and TH04 taught me about " "agents, verification and knowledge that compounds across projects." msgstr "什麼手動重新和重建TH08,TH095和TH04教我關於程式設計助手,驗證和知識,跨專案的化合物。" -#: website/public/blog/index.html:208 +#: website/public/blog/index.html:207 website/public/blog/index.html:222 msgctxt "page:blog/index.html" msgid "Read the article" msgstr "閱讀文章" -#: website/public/blog/index.html:211 +#: website/public/blog/index.html:225 msgctxt "page:blog/index.html" msgid "By N0zoM1z0 · 10 October 2026" msgstr "透過N0zoM1z0*10十月2026" #. {ph0}: -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 +#: website/public/blog/reverse-engineering-models/index.html:883 #: website/public/blog/touhou-reconstruction/index.html:1080 #: website/public/examples/dino-lab/index.html:475 #: website/public/faq/index.html:573 @@ -96,6 +97,8 @@ msgid "" msgstr "對逆向工程的思考,借鑑與 REA 和AI程式設計助手。" #: website/public/blog/index.html:75 website/public/blog/index.html:88 +#: website/public/blog/reverse-engineering-models/index.html:75 +#: website/public/blog/reverse-engineering-models/index.html:88 #: website/public/blog/touhou-reconstruction/index.html:75 #: website/public/blog/touhou-reconstruction/index.html:88 #: website/public/examples/dino-lab/index.html:75 @@ -130,6 +133,7 @@ msgid "" msgstr "REA-瞭解軟體的工作原理。 逆向工程與你的程式設計助手." #: website/public/blog/index.html:108 +#: website/public/blog/reverse-engineering-models/index.html:108 #: website/public/blog/touhou-reconstruction/index.html:108 #: website/public/examples/dino-lab/index.html:109 #: website/public/faq/index.html:108 @@ -150,6 +154,7 @@ msgid "REA home" msgstr "REA 首頁" #: website/public/blog/index.html:112 +#: website/public/blog/reverse-engineering-models/index.html:112 #: website/public/blog/touhou-reconstruction/index.html:112 #: website/public/examples/dino-lab/index.html:113 #: website/public/faq/index.html:112 @@ -170,6 +175,7 @@ msgid "Main navigation" msgstr "主導航" #: website/public/blog/index.html:130 +#: website/public/blog/reverse-engineering-models/index.html:130 #: website/public/blog/touhou-reconstruction/index.html:130 #: website/public/examples/dino-lab/index.html:131 #: website/public/faq/index.html:130 @@ -190,6 +196,7 @@ msgid "REA on GitHub" msgstr "在 GitHub 檢視 REA" #: website/public/blog/index.html:150 +#: website/public/blog/reverse-engineering-models/index.html:150 #: website/public/blog/touhou-reconstruction/index.html:150 #: website/public/examples/dino-lab/index.html:151 #: website/public/faq/index.html:150 @@ -210,6 +217,7 @@ msgid "Join REA on Discord" msgstr "加入 REA 的 Discord 社群" #: website/public/blog/index.html:169 +#: website/public/blog/reverse-engineering-models/index.html:169 #: website/public/blog/touhou-reconstruction/index.html:169 #: website/public/examples/dino-lab/index.html:170 #: website/public/faq/index.html:169 @@ -229,7 +237,7 @@ msgctxt "shared" msgid "Follow REA on X" msgstr "在 X 上關注 REA" -#: website/public/blog/index.html:230 +#: website/public/blog/index.html:244 msgctxt "page:blog/index.html" msgid "Back to top" msgstr "回到頂部" @@ -10634,6 +10642,7 @@ msgid "Same spacing: 256 ÷ 16 = 16 angle units = 22.5°" msgstr "相同間距:256÷16=16角度單位=22.5°" #: website/public/blog/index.html:114 +#: website/public/blog/reverse-engineering-models/index.html:114 #: website/public/blog/touhou-reconstruction/index.html:114 #: website/public/examples/dino-lab/index.html:115 #: website/public/faq/index.html:114 @@ -10654,6 +10663,7 @@ msgid "Showcases" msgstr "案例展示" #: website/public/blog/index.html:115 +#: website/public/blog/reverse-engineering-models/index.html:115 #: website/public/blog/touhou-reconstruction/index.html:115 #: website/public/examples/dino-lab/index.html:116 #: website/public/faq/index.html:115 @@ -10674,6 +10684,7 @@ msgid "Blog" msgstr "部落格" #: website/public/blog/index.html:113 +#: website/public/blog/reverse-engineering-models/index.html:113 #: website/public/blog/touhou-reconstruction/index.html:113 #: website/public/examples/dino-lab/index.html:114 #: website/public/faq/index.html:113 @@ -10694,6 +10705,7 @@ msgid "Get started" msgstr "開始使用" #: website/public/blog/index.html:116 +#: website/public/blog/reverse-engineering-models/index.html:116 #: website/public/blog/touhou-reconstruction/index.html:116 #: website/public/examples/dino-lab/index.html:117 #: website/public/faq/index.html:116 @@ -10713,7 +10725,8 @@ msgctxt "shared" msgid "Guides" msgstr "指南" -#: website/public/blog/index.html:222 +#: website/public/blog/index.html:236 +#: website/public/blog/reverse-engineering-models/index.html:875 #: website/public/blog/touhou-reconstruction/index.html:1072 #: website/public/examples/dino-lab/index.html:467 #: website/public/faq/index.html:565 @@ -10733,7 +10746,8 @@ msgctxt "shared" msgid "Source" msgstr "原始碼" -#: website/public/blog/index.html:223 +#: website/public/blog/index.html:237 +#: website/public/blog/reverse-engineering-models/index.html:876 #: website/public/blog/touhou-reconstruction/index.html:1073 #: website/public/examples/dino-lab/index.html:468 #: website/public/faq/index.html:566 @@ -10753,7 +10767,8 @@ msgctxt "shared" msgid "MIT license" msgstr "MIT 許可證" -#: website/public/blog/index.html:224 +#: website/public/blog/index.html:238 +#: website/public/blog/reverse-engineering-models/index.html:877 #: website/public/blog/touhou-reconstruction/index.html:1074 #: website/public/examples/dino-lab/index.html:469 #: website/public/faq/index.html:567 @@ -10773,7 +10788,8 @@ msgctxt "shared" msgid "Join the community" msgstr "加入社群" -#: website/public/blog/index.html:225 +#: website/public/blog/index.html:239 +#: website/public/blog/reverse-engineering-models/index.html:878 #: website/public/blog/touhou-reconstruction/index.html:1075 #: website/public/examples/dino-lab/index.html:470 #: website/public/faq/index.html:568 @@ -11701,6 +11717,1146 @@ msgstr "" "若要檢查 HTTP 請求與回應本文,請使用{ph0}Fiddler Everywhere:SAZ 擷取、MCP 與公開技能{ph1}。匯出 SAZ ? " "HAR 1.2 可在 REA 中離線取得擷取 Evidence,也可以連接 Everywhere 的 MCP 伺服器,讓代理檢查已擷取的流量。" +#. {ph0}:
+#: website/public/blog/index.html:200 +#, python-brace-format +msgctxt "page:blog/index.html" +msgid "Model specialization{ph0}Essay" +msgstr "專用模型{ph0}隨筆" + +#: website/public/blog/index.html:202 +msgctxt "page:blog/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "逆向工程需要更大的模型嗎?" + +#: website/public/blog/index.html:203 +msgctxt "page:blog/index.html" +msgid "" +"What Touhou reconstruction suggests about general models, specialist models " +"and learning from compiler feedback." +msgstr "從 Touhou 重建的經驗,探討通用模型、專用模型,以及如何從編譯器回饋中學習。" + +#: website/public/blog/index.html:210 +msgctxt "page:blog/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "作者 N0zoM1z0 · 2026 年 10 月 13 日" + +#: website/public/blog/reverse-engineering-models/index.html:103 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Skip to content" +msgstr "跳轉到內容" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:194 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Home{ph1} / {ph2}Blog{ph3} / Models and RE" +msgstr "{ph0}首頁{ph1} / {ph2}部落格{ph3} / 模型與逆向工程" + +#: website/public/blog/reverse-engineering-models/index.html:197 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Essay" +msgstr "隨筆" + +# Reviewed for technical meaning and readability; preserve the distinction +# between historical evidence and proposed experiments. +#: website/public/blog/reverse-engineering-models/index.html:198 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model?" +msgstr "逆向工程需要更大的模型嗎?" + +#: website/public/blog/reverse-engineering-models/index.html:199 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "By N0zoM1z0 · 13 October 2026" +msgstr "作者 N0zoM1z0 · 2026 年 10 月 13 日" + +#: website/public/blog/reverse-engineering-models/index.html:201 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Takeaway" +msgstr "要點" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:203 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Model capability changes the hypotheses an agent can find.{ph1} Later " +"sessions have solved problems that earlier work left unresolved." +msgstr "{ph0}模型能力會影響 agent 能提出哪些假設。{ph1} 後來的工作解決了早期嘗試未能解決的問題。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:211 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A familiar compiler gives specialization something concrete to " +"learn.{ph1} Some exact matches depend on narrow, reusable source patterns." +msgstr "{ph0}熟悉的編譯器為專用模型提供了具體的學習對象。{ph1} 有些精確匹配依賴細小但可以複用的原始碼模式。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:218 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Give repository knowledge a fair comparison.{ph1} A smaller model with " +"good retrieval may already know enough to make progress." +msgstr "{ph0}也要公平評估程式碼倉庫裡的知識。{ph1} 較小的模型配合良好的檢索,可能已經掌握了足以推進工作的知識。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:223 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Train the next useful experiment, and test its oracle.{ph1} The value " +"of feedback depends on what the checker actually verifies." +msgstr "{ph0}訓練模型選擇下一個有價值的實驗,同時檢驗它使用的驗證器。{ph1} 回饋是否有用,取決於驗證器究竟檢查了什麼。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:230 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Measure accepted reconstruction against time and cost.{ph1} That is the" +" result I want from the whole agent." +msgstr "{ph0}結合時間和成本,評估透過驗證的重建成果。{ph1} 這是我希望從整個 agent 工作流程中獲得的結果。" + +#: website/public/blog/reverse-engineering-models/index.html:241 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "In this article" +msgstr "在本文中" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:243 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What better models changed{ph1}" +msgstr "{ph0}更強的模型改變了什麼{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:244 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Why specialize?{ph1}" +msgstr "{ph0}為什麼考慮專用模型?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:245 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Where experience lives{ph1}" +msgstr "{ph0}這些經驗應該存在哪裡?{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:246 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}Learning the next experiment{ph1}" +msgstr "{ph0}學習選擇下一個有價值的實驗{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:247 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}RE and reinforcement learning{ph1}" +msgstr "{ph0}逆向工程與強化學習{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:248 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}When the oracle is wrong{ph1}" +msgstr "{ph0}當驗證器出錯時{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:249 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}A comparison worth running{ph1}" +msgstr "{ph0}值得做的對照實驗{ph1}" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:250 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "{ph0}What kind of agent?{ph1}" +msgstr "{ph0}這意味著怎樣的 agent?{ph1}" + +#: website/public/blog/reverse-engineering-models/index.html:258 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What better models changed" +msgstr "更強的模型改變了什麼" + +#: website/public/blog/reverse-engineering-models/index.html:259 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Since August 2026, I have been exploring how much reverse engineering an " +"agent can carry out with access to a program and a way to check its work. " +"Most of my experience comes from reconstructing games, especially Touhou. As" +" I have changed models, the repositories have kept a record of what each " +"session managed to recover." +msgstr "" +"從 2026 年 8 月開始,我一直在探索:如果給 agent " +"訪問程式的能力,以及驗證自身工作的手段,它能獨立完成多少逆向工作?我的經驗主要來自遊戲重建,尤其是東方系列。隨著我更換模型,程式碼倉庫記錄了每次工作還原出的內容。" + +#: website/public/blog/reverse-engineering-models/index.html:267 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of that work aims at exact reconstruction: we compile the maintained " +"source under a pinned historical toolchain and check whether it reproduces " +"the target function. When a later model succeeds where earlier work stalled," +" the source changes show what made that progress possible." +msgstr "" +"這些工作很大一部分追求精確重建:用固定版本的歷史工具鏈編譯我們維護的原始碼,檢查它能否復現目標函式。當後來的模型解決了早期工作卡住的問題,我們可以從原始碼變化中看出,是什麼促成了這次進展。" + +#: website/public/blog/reverse-engineering-models/index.html:274 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The temporary values had to stay alive together" +msgstr "臨時值需要同時保持有效" + +#: website/public/blog/reverse-engineering-models/index.html:275 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Much of a TH09 attack function's logic had already been reconstructed, but " +"the compiler still stored temporary results differently from the original. " +"The remaining problem was how long those results needed to stay alive and " +"when their storage could be reused." +msgstr "" +"TH09 " +"中一個攻擊函式的大部分邏輯已經還原,但編譯器對臨時結果的儲存安排仍然與原版不同。剩下的問題在於:這些結果的生命週期應該多長,編譯器何時可以複用它們的儲存空間?" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:282 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A {ph0}GPT-6-Sol checkpoint{ph1} recorded this mismatch after testing " +"several ordinary source arrangements. When {ph2}GPT-6.1-Sol returned to the " +"problem{ph3}, it found a useful hypothesis about how long those temporary " +"values needed to stay alive." +msgstr "" +"{ph0}GPT-6-Sol 的一次工作記錄{ph1}表明,嘗試幾種常見的原始碼寫法後,差異仍未消除。後來,{ph2}GPT-6.1-Sol " +"重新研究這個問題{ph3},提出了一個有價值的假設:關鍵可能在於這些臨時值的生命週期。" + +#: website/public/blog/reverse-engineering-models/index.html:296 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The function produced temporary results and copied them into animation " +"positions. In C++, a temporary result stays alive until the expression using" +" it finishes. Grouping the real operations into one expression kept those " +"results alive together, so the compiler could no longer reuse the same " +"storage for all of them." +msgstr "" +"這個函式會產生臨時結果,再把它們複製到動畫的位置資料中。在 C++ " +"中,臨時結果會一直存在,直到使用它的表示式執行完畢。把實際操作放進同一個表示式,就能讓這些結果同時存活,編譯器也就不能為它們全部複用同一塊儲存空間。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:303 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"One result still shared storage with a value used later for collision " +"checks. Giving that value its own lifetime resolved the remaining overlap. " +"After several targeted experiments, {ph0}a clean rebuild confirmed that the " +"full function matched{ph1}." +msgstr "" +"其中一個結果仍然與稍後用於碰撞檢查的值共享儲存。給那個值單獨的生命週期後,最後一處重疊也消失了。經過幾次有針對性的實驗,{ph0}一次乾淨的重新構建確認,整個函式都已匹配{ph1}。" + +#: website/public/blog/reverse-engineering-models/index.html:312 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What interests me is how the discovery and the tests worked together. The " +"lifetime hypothesis gave the agent a new direction; compiler feedback helped" +" it refine that hypothesis into a source arrangement that matched." +msgstr "" +"我感興趣的是,發現與驗證如何共同推進工作。生命週期的假設給 agent 指明瞭新方向;編譯器的回饋又幫助它逐步調整原始碼,直到找到匹配的寫法。" + +#: website/public/blog/reverse-engineering-models/index.html:318 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A different control-flow graph" +msgstr "換一種控制流結構" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:319 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A second TH09 function shows why that new direction can matter. Here, the " +"obstacle was how several branches shared their final work. " +"{ph0}GPT-6.1-Sol's earlier work{ph1} got parts of the function to match, but" +" the branches still joined up differently from the original." +msgstr "" +"TH09 的另一個函式說明了,新方向為什麼重要。這次的難點是多個分支如何共享末尾的操作。{ph0}GPT-6.1-Sol " +"之前的工作{ph1}已經讓函式的一些部分匹配,但分支匯合的方式仍與原版不同。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:330 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}GPT-6-Astra changed the surrounding control-flow graph{ph1}. The main " +"paths now led to a shared final update and return. In that source structure," +" the compiler combined the branches in the same way as the original. The " +"complete function matched, and a {ph2}separate rebuild check confirmed " +"it{ph3}." +msgstr "" +"{ph0}GPT-6-Astra " +"改寫了外圍的控制流圖{ph1},讓主要路徑匯入共同的最終更新與返回。在這種原始碼結構下,編譯器合併分支的方式與原版一致。整個函式實現了匹配,{ph2}另一次獨立的重新構建也確認了這一結果{ph3}。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:342 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Changing the representation opened a more productive search space.{ph1}" +" Both cases give me a reason to take general model capability seriously: an " +"agent can keep trying local variations for a long time before finding a " +"better way to express the surrounding work." +msgstr "" +"{ph0}換一種表達方式,開啟了更有價值的搜尋空間。{ph1} 這兩個例子讓我認真看待通用模型的能力:agent " +"可能花很長時間嘗試局部變化,才找到一種更好的整體寫法。" + +#: website/public/blog/reverse-engineering-models/index.html:351 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"At the same time, the later sessions started with earlier source and " +"recorded failures. That accumulated work was part of their advantage. The " +"history lets us inspect the discoveries and their checks; a controlled " +"comparison would help separate the effect of the model from the experience " +"it inherited." +msgstr "" +"不過,後來的工作也繼承了之前的原始碼和失敗記錄。這些積累本身就是優勢的一部分。歷史記錄讓我們可以檢查發現及其驗證過程;要區分模型能力和繼承經驗各自帶來的幫助,還需要對照實驗。" + +#: website/public/blog/reverse-engineering-models/index.html:358 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is where the question becomes interesting to me. Some of the progress " +"came from finding a new representation, while much of the remaining work " +"involved testing source forms against a familiar compiler. How much needs " +"broad reasoning ability, and how much could a model learn through repeated " +"experience with that compiler and code?" +msgstr "" +"這正是我覺得有趣的地方。有些進展來自新的表達方式,剩下的大量工作則是在熟悉的編譯器上試驗不同寫法。其中有多少需要廣泛的推理能力?又有多少可以透過反覆接觸這個編譯器和這些程式碼來學會?" + +#: website/public/blog/reverse-engineering-models/index.html:368 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why might a specialist do well?" +msgstr "為什麼專用模型可能做得很好?" + +#: website/public/blog/reverse-engineering-models/index.html:369 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Touhou gives us a concrete reason to expect that experience to help. Much of" +" the game code comes from the same author, ZUN, so recurring habits are a " +"reasonable starting assumption. The repositories back that up with useful " +"examples: related loops and helper arrangements have supplied hypotheses " +"across games." +msgstr "" +"東方系列給了我們一個具體的理由,去期待經驗積累能發揮作用。大量遊戲程式碼出自同一個作者 " +"ZUN,因此,把反覆出現的程式設計習慣作為初始假設是合理的。程式碼倉庫也提供了實際例子:相似的迴圈和輔助函式組織方式,曾為其他遊戲的重建提供假設。" + +#: website/public/blog/reverse-engineering-models/index.html:376 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those source patterns become more specific when we include the compiler. " +"Under a particular version and set of options, small changes in source can " +"produce repeatable differences in machine code. Some of those differences " +"are surprisingly obscure." +msgstr "把編譯器也考慮進去,這些原始碼模式就更加具體了。在固定版本和選項下,原始碼的小變化可能穩定地產生不同的機器碼。其中一些規律藏得很深。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: Supervisor::LoadDat +#. {ph4}: +#: website/public/blog/reverse-engineering-models/index.html:382 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In TH095, for example, {ph0}even the name used for a local variable could " +"change where VC7.1 stored it{ph1}. Moving the declaration alone did not " +"solve the layout, but an earlier background function had revealed a naming " +"pattern that affected the compiler's choice. That gave us a more promising " +"hypothesis for {ph2}the reconstruction of {ph3}{ph4}." +msgstr "" +"以 TH095 為例,{ph0}連局部變數的名字,都可能改變 VC7.1 " +"為它安排的儲存位置{ph1}。只移動宣告並不能解決佈局問題,但先前重建的一個背景函式揭示了會影響編譯器選擇的命名模式。這為{ph2}重建 " +"{ph3}{ph4}提供了更有希望的假設。" + +#: website/public/blog/reverse-engineering-models/index.html:396 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reusing that pattern for the file-size variable produced the required layout" +" without adding storage. The full function then matched." +msgstr "把這個模式用於表示檔案大小的變數,不增加額外儲存就得到了所需佈局。隨後,整個函式實現了匹配。" + +#: website/public/blog/reverse-engineering-models/index.html:401 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This is the sort of narrow detail a general model may not know when it " +"arrives. A specialist trained on this compiler could encounter many such " +"cases and learn which source variations are worth testing first." +msgstr "這類細節非常具體,通用模型第一次接觸時未必知道。而針對這個編譯器訓練的專用模型,可以接觸許多類似案例,學會哪些原始碼變化值得優先嚐試。" + +#: website/public/blog/reverse-engineering-models/index.html:407 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The opportunity is especially clear in final matching problems where we " +"already understand the behavior. We are then asking which ordinary source " +"form this compiler turns into the observed instructions. Specialization " +"could help the model propose those forms more efficiently, while the target " +"still determines which hypotheses survive." +msgstr "" +"當我們已經理解函式行為,只剩最後的匹配差異時,這個機會尤其明顯。此時的問題是:這個編譯器會把哪一種普通寫法編譯成眼前的指令?專用訓練可能讓模型更高效地提出這些寫法,而最終由目標程式決定哪些假設成立。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:415 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The useful patterns would have to retain their context, though. TH08 uses an" +" earlier Visual C++ version than TH095 and TH09. TH04 uses a different DOS-" +"era compiler, and its {ph0}player reconstruction{ph1} needed different " +"hypotheses about source patterns and how the compiled code was combined into" +" an executable. Shared authorship gives us a prior, but each target tells us" +" whether it applies. Distinguishing those contexts is part of what a " +"specialist would need to learn." +msgstr "" +"但這些模式必須保留適用的上下文。TH08 使用的 Visual C++ 版本早於 TH095 和 TH09。TH04 用的是另一種 DOS " +"時代的編譯器,其{ph0}玩家邏輯重建{ph1}需要不同的假設,既涉及原始碼寫法,也涉及編譯後的程式碼如何連結成可執行檔案。同一作者為我們提供了先驗,具體目標則告訴我們它是否適用。區分這些情況,也是專用模型需要學會的事。" + +#: website/public/blog/reverse-engineering-models/index.html:431 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Where should that experience live?" +msgstr "這些經驗應該存在哪裡?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:432 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before deciding to teach those patterns through model training, I would look" +" at the knowledge we already keep in the repository. In the {ph0}previous " +"essay{ph1}, I wrote about it becoming the project's working memory. That " +"memory includes compiler lessons, along with the source and failed " +"experiments that made them useful." +msgstr "" +"在決定透過訓練讓模型學會這些模式之前,我會先看看程式碼倉庫裡已有的知識。在{ph0}上一篇文章{ph1}中,我寫過:倉庫正在成為專案的工作記憶。這裡儲存著對編譯器的認識,也儲存著相關原始碼和失敗實驗,讓這些經驗有據可查。" + +#: website/public/blog/reverse-engineering-models/index.html:441 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"By retrieving that record, an agent can start with a known result and " +"inspect how we reached it. It can also avoid alternatives that have already " +"failed in the same context. The starting point improves without changing the" +" model's weights." +msgstr "" +"檢索這些記錄後,agent 可以從已知結果出發,看看我們是如何得到它的,也可以避開在相同條件下已經失敗的方案。模型的參數沒有改變,工作的起點卻提高了。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:447 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"When reconstructing TH09's enemy-spawn function, a {ph0}GPT-6-Luna-max " +"session{ph1} drew a hypothesis from TH08's corresponding source family. That" +" earlier source suggested how to structure the loop and handle failures " +"within it. TH09's own evidence supplied the game-specific details, and clean" +" rebuilds confirmed the complete match." +msgstr "" +"重建 TH09 的敵人生成函式時,{ph0}GPT-6-Luna-max 的一次工作{ph1}從 TH08 " +"對應的原始碼中找到了假設。之前的寫法提示了迴圈該如何組織,以及內部失敗該如何處理。TH09 " +"自身的證據補上了遊戲特有的細節,乾淨的重新構建確認了整個函式的匹配。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:458 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}\"The model did not know that compiler quirk\" and \"the model could " +"not use it\" are different problems.{ph1} Retrieval may solve the first, but" +" turning that fact into a useful candidate still takes work. And if the " +"candidate fails, the model must decide what the result means for its next " +"attempt. Knowing the relevant pattern is only the beginning of that process." +msgstr "" +"{ph0}“模型不知道這個編譯器特性”和“模型不會利用它”,是兩個不同的問題。{ph1} " +"檢索可能解決前者,但把知識變成有價值的候選原始碼,仍然需要能力。如果候選方案失敗了,模型還得判斷這次結果對下一次嘗試意味著什麼。知道相關模式,只是這個過程的起點。" + +#: website/public/blog/reverse-engineering-models/index.html:468 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For that reason, I would include a smaller general model with good retrieval" +" in any comparison. Giving it the same library of experience would help us " +"identify what training adds: better candidate generation, better decisions " +"after feedback, or both." +msgstr "" +"所以,在任何對照實驗中,我都會加入一個具備良好檢索能力的小型通用模型。給它相同的經驗庫,才能看清訓練究竟增加了什麼:更好的候選方案、更好的回饋後決策,還是兩者都有?" + +#: website/public/blog/reverse-engineering-models/index.html:476 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Learning the next useful experiment" +msgstr "學習選擇下一個有價值的實驗" + +#: website/public/blog/reverse-engineering-models/index.html:477 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Those decisions after feedback are what I would most like to study. In " +"agentic reconstruction, the model proposes an explanation and tests it " +"against the program. Even when the candidate fails, the result can narrow " +"the remaining possibilities and suggest a more useful next experiment." +msgstr "" +"回饋之後如何決策,是我最想研究的部分。在 agent " +"驅動的重建中,模型提出解釋,再用程式來驗證。即使候選方案失敗了,結果也可能縮小剩餘的可能性,提示下一步更值得嘗試什麼。" + +#: website/public/blog/reverse-engineering-models/index.html:484 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Consider the temporary-results example again. Its final source shows the " +"arrangement that worked, but the route to that source contains more " +"information. Each of the following experiments helped identify what still " +"needed to change." +msgstr "再看前面的臨時結果例子。最終原始碼展示了成功的寫法,但得到它的過程包含更多資訊。下面的每次實驗,都幫助我們確定了還有什麼需要改變。" + +#: website/public/blog/reverse-engineering-models/index.html:497 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Experiment" +msgstr "實驗" + +#: website/public/blog/reverse-engineering-models/index.html:498 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What its result taught us" +msgstr "結果告訴了我們什麼" + +#: website/public/blog/reverse-engineering-models/index.html:503 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Try a different way to copy the results" +msgstr "嘗試另一種複製結果的方式" + +#: website/public/blog/reverse-engineering-models/index.html:504 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "The copy code changes, but the function still differs." +msgstr "複製程式碼改變了,但函式仍有差異。" + +#: website/public/blog/reverse-engineering-models/index.html:509 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Use the returned values directly" +msgstr "直接使用回傳值" + +#: website/public/blog/reverse-engineering-models/index.html:510 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Copying follows the original pattern, but temporary storage still differs." +msgstr "複製方式與原版一致,但臨時儲存佈局仍有差異。" + +#: website/public/blog/reverse-engineering-models/index.html:516 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the temporary results alive together" +msgstr "讓臨時結果同時保持有效" + +#: website/public/blog/reverse-engineering-models/index.html:517 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"They get separate storage, but one still overlaps a value used later for " +"collision checks." +msgstr "它們得到了各自的儲存空間,但其中一個仍與稍後用於碰撞檢查的值重疊。" + +#: website/public/blog/reverse-engineering-models/index.html:523 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Keep the collision-check value separate" +msgstr "讓碰撞檢查的值擁有獨立儲存" + +#: website/public/blog/reverse-engineering-models/index.html:524 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A clean rebuild confirms the complete match." +msgstr "乾淨的重新構建確認了整個函式的匹配。" + +#: website/public/blog/reverse-engineering-models/index.html:529 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Selected experiments from the attack-function reconstruction above, grouped " +"by what they taught us." +msgstr "選自前面攻擊函式的重建實驗,按每次得到的認識整理。" + +#: website/public/blog/reverse-engineering-models/index.html:533 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A training record that keeps this sequence can teach more than the final " +"source alone. It connects each proposed change to an observed result and the" +" next decision. Keeping ineffective variations matters too: they tell a " +"later agent which hypotheses have already been tested in that context." +msgstr "" +"儲存這個過程的訓練記錄,比單獨儲存最終原始碼能教會模型更多東西。它把每個改動、觀察到的結果和下一步決策聯絡起來。無效的嘗試也值得保留:後來的 agent" +" 可以據此知道,在這個上下文中,哪些假設已經檢驗過。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:540 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}I would want the model to learn how to use feedback.{ph1} A neutral " +"result is a reason to reconsider the variation; a changed mismatch may point" +" to another cause. When local edits stop being informative, the agent should" +" be able to revisit the source representation or inspect the evidence again." +msgstr "" +"{ph0}我希望模型學會如何利用回饋。{ph1} " +"結果沒有變化,可能意味著該重新考慮這個改動;差異發生變化,則可能指向另一個原因。當局部修改不再提供有效資訊時,agent " +"應該可以重新考慮原始碼的整體表達,或者回頭檢查證據。" + +#: website/public/blog/reverse-engineering-models/index.html:549 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Learning to make those choices requires autonomy. Sometimes the useful next " +"step is inspecting another caller rather than compiling another edit. A " +"rigid sequence of required rewrites would remove that choice, along with " +"part of the behavior we want the model to learn." +msgstr "" +"學會這些選擇,需要自主性。有時,更有價值的下一步是檢查另一個呼叫者,而不是再修改一次原始碼並編譯。如果強制按照固定順序改寫,就會剝奪這種選擇,也失去一部分我們希望模型學會的行為。" + +#: website/public/blog/reverse-engineering-models/index.html:558 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Why RE is interesting for reinforcement learning" +msgstr "為什麼逆向工程值得用來探索強化學習" + +#: website/public/blog/reverse-engineering-models/index.html:559 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Bounded reconstruction gives us a practical environment for studying these " +"choices. Once the target and compiler are pinned, many source experiments " +"produce quick, repeatable feedback. The agent can compile a candidate, " +"inspect the mismatch and use that observation to choose its next step." +msgstr "" +"範圍明確的重建任務,為研究這些選擇提供了一個實際環境。目標和編譯器版本固定之後,許多原始碼實驗都能快速給出可重複的回饋。agent " +"可以編譯候選原始碼、檢查差異,再根據觀察選擇下一步。" + +#: website/public/blog/reverse-engineering-models/index.html:566 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Reinforcement learning could train that decision-making process through the " +"feedback it receives. A candidate accepted by a defined check gives us a " +"concrete outcome, while the sequence of attempts lets us observe how much " +"work it took to reach it." +msgstr "" +"強化學習可以利用這些回饋,訓練模型的決策過程。候選原始碼透過明確定義的檢查,就給出了一個具體成果;而嘗試的過程,讓我們可以看到實現它花了多少功夫。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#: website/public/blog/reverse-engineering-models/index.html:572 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"There is already research supporting this direction. {ph0}LLM4Decompile{ph1}" +" studies models specialized for decompilation. {ph2}AutoDecompiler{ph3} " +"trains multi-turn refinement using compiler and execution feedback. Their " +"studies focus on functional recovery. For this work, I would use them as a " +"starting point for the related task of finding source that matches a " +"historical compiler's output." +msgstr "" +"已有研究支援這個方向。{ph0}LLM4Decompile{ph1}研究專門用於反編譯的模型。{ph2}AutoDecompiler{ph3}利用編譯和執行回饋,訓練多輪改進能力。這些研究關注的是功能還原。對於我們的工作,我會以它們為起點,研究一個相關任務:找到能復現歷史編譯器輸出的原始碼。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:584 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To reach such a well-defined task, though, we may first need to establish " +"what a function owns or devise a new runtime measurement. In TH08, for " +"example, a {ph0}collision difference led back to how the original program " +"handled floating-point calculations{ph1}. Before the agent could test a " +"useful correction, it had to work out what to measure." +msgstr "" +"不過,要得到這樣一個定義明確的任務,有時得先確定函式負責哪些資源,或者設計新的方法觀察程式執行時的行為。在 TH08 " +"中,{ph0}一次碰撞差異最終追溯到原版處理浮點計算的方式{ph1}。agent 必須先弄清楚該測量什麼,才能驗證有價值的修正。" + +#: website/public/blog/reverse-engineering-models/index.html:595 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This suggests another role for a broadly capable model: helping make the " +"problem checkable in the first place. Once that check exists, we can " +"investigate how far a learned search policy can get with it." +msgstr "這提示了能力全面的模型的另一個作用:先把問題變得可驗證。驗證手段建立起來後,我們才可以研究,學出來的搜尋策略能走多遠。" + +#: website/public/blog/reverse-engineering-models/index.html:603 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "When the oracle is wrong" +msgstr "當驗證器出錯時" + +#: website/public/blog/reverse-engineering-models/index.html:604 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Once we train against that check, its coverage becomes part of what the " +"model learns. I call the reference or checker an oracle. Even if it gives a " +"repeatable answer, we still need to understand what that answer covers." +msgstr "" +"一旦用某項檢查來訓練模型,它的覆蓋範圍就會成為學習環境的一部分。我把這種參考標準或驗證器稱為 " +"oracle。即使它能給出可重複的答案,我們也必須知道,這個答案覆蓋了什麼。" + +#: website/public/blog/reverse-engineering-models/index.html:610 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"TH08 showed how much can hide outside that coverage. Some reconstructed " +"functions passed their exact comparisons with wrong floating constants. The " +"comparator adjusted relocated addresses before checking instructions, but it" +" checked the values behind those addresses only when they had been " +"explicitly recorded for verification. Other literal references could pass " +"without their values being examined." +msgstr "" +"TH08 " +"展示了檢查範圍之外可能藏著多少問題。一些重建函式使用了錯誤的浮點常量,卻仍然透過了精確比較。比較器會先調整重定位地址,再檢查指令;但只有明確登記過的常量,才會進一步檢查地址指向的值。其他常量引用,即使值沒被檢查,也可能透過。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: 1.0f +#. {ph3}: 32.0f +#: website/public/blog/reverse-engineering-models/index.html:619 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To close that gap, a {ph0}wider audit{ph1} found incorrect constants in " +"functions that had already been accepted. In one calculation, the " +"reconstructed source added {ph2} where the original added {ph3}." +msgstr "" +"為了補上這個漏洞,{ph0}一次更全面的審計{ph1}在已經透過檢查的函式中找到了錯誤常量。有一個計算中,重建原始碼加的是 {ph2},而原版加的是 " +"{ph3}。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:629 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}A learner rewarded by the old check could learn to produce the wrong " +"reconstruction.{ph1} We had not trained an RL model against this oracle; the" +" observed failure was in the check itself. But using that check as a reward " +"would have made the same blind spot part of the learning environment." +msgstr "" +"{ph0}如果用舊檢查的結果作為獎勵,模型可能學會生成錯誤的重建原始碼。{ph1} 我們沒有用這個驗證器訓練 RL " +"模型;實際觀察到的是檢查本身的漏洞。但如果把它用作獎勵,同一個盲點也會進入學習環境。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:639 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"A functional test can have a similar blind spot. {ph0}Differential-fuzzing " +"research on LLM decompilers{ph1} has found behavior differences beyond the " +"supplied tests. Passing those tests therefore needs to be read in terms of " +"the cases they exercise, just as an instruction match needs to be read in " +"terms of the bytes and data it checks." +msgstr "" +"功能測試也可能存在類似盲點。{ph0}針對 LLM " +"反編譯器的差分模糊測試研究{ph1}發現,在已有測試之外,程式行為仍可能不同。因此,理解“測試透過”時,必須看它實際覆蓋了哪些情況;理解“指令匹配”時,也必須看它檢查了哪些位元組和資料。" + +#: website/public/blog/reverse-engineering-models/index.html:649 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Before using either kind of check as a reward, I would test it with " +"deliberate failures. I would also keep final acceptance outside the " +"candidate's editable source, so the model has to satisfy the check through " +"its reconstruction. Otherwise, something like a byte array copied from the " +"target could satisfy a naive score without recovering useful source." +msgstr "" +"在把任何一種檢查用作獎勵之前,我都會用刻意構造的錯誤來測試它。我還會把最終驗收機制放在候選原始碼可修改的範圍之外,讓模型透過正確重建來滿足檢查。否則,直接複製目標程式的位元組陣列,也可能騙過簡單的評分,卻沒有還原出有用的原始碼。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:657 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Improving the learner and improving its oracle belong to the same " +"research problem.{ph1} As the learner gets better at optimizing the feedback" +" we give it, understanding that feedback becomes more important too." +msgstr "{ph0}改進模型和改進它的驗證器,屬於同一個研究問題。{ph1} 模型越擅長最佳化我們給它的回饋,我們就越需要理解回饋本身。" + +#: website/public/blog/reverse-engineering-models/index.html:667 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "A comparison worth running" +msgstr "值得做的對照實驗" + +#: website/public/blog/reverse-engineering-models/index.html:668 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"With those checks in place, I would start the comparison on a fixed VC7.1 " +"task family. First, I would establish baselines for a strong general model " +"and a smaller one. Adding repository knowledge to the smaller model would " +"show what retrieval changes. From there, supervised specialization and an " +"RL-trained version would let us examine what training adds." +msgstr "" +"具備這些檢查之後,我會從一組固定的 VC7.1 " +"任務開始比較。先為強通用模型和小型通用模型建立基線,再給小模型加入倉庫知識,觀察檢索帶來的變化。接著比較監督訓練的專用模型,以及在此基礎上進行 RL " +"訓練的版本,看看訓練增加了什麼。" + +#: website/public/blog/reverse-engineering-models/index.html:676 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"To make those comparisons informative, each model would receive the same " +"target evidence and tools. For the training-specific comparisons, I would " +"keep the base model and available knowledge fixed as well. Repeated trials " +"would help distinguish a reliable search strategy from a lucky candidate." +msgstr "" +"為了讓比較有意義,每個模型都應獲得相同的目標證據和工具。專門比較訓練效果時,還要固定基礎模型和可用知識。重複實驗有助於區分可靠的搜尋策略與偶然成功的候選方案。" + +#: website/public/blog/reverse-engineering-models/index.html:683 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would then separate two starting conditions: reconstructing a function " +"from its instructions, and closing the last few differences in maintained " +"source. A specialist might be excellent at the second task while a general " +"model does much of the work needed to reach it. Measuring them separately " +"would reveal that division of work." +msgstr "" +"我還會區分兩種起點:從指令開始重建函式,以及在已有原始碼中消除最後幾處差異。專用模型可能很擅長後者,而通用模型承擔了到達這個階段的大部分工作。分別評估,才能看清這種分工。" + +#: website/public/blog/reverse-engineering-models/index.html:691 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both tasks need genuinely held-out examples. Because related Touhou games " +"share engine code, holding out a game's name would still allow nearly " +"identical functions to appear in training. I would instead hold out source " +"families and keep their accepted answers out of both training and retrieval." +msgstr "" +"兩類任務都需要真正未見過的測試案例。東方系列的相關遊戲會共享引擎程式碼,只留出某個遊戲,仍可能讓幾乎相同的函式進入訓練集。我會改為按相關原始碼家族留出測試集,並把它們透過驗證的答案同時排除在訓練資料和檢索庫之外。" + +#: website/public/blog/reverse-engineering-models/index.html:698 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"On those examples, the outcome would be complete, independently validated " +"matches. Giving each model the same candidate or compile budget would help " +"compare search quality. Measuring elapsed time and total cost, including " +"compilation, would tell us whether that quality produces an efficient " +"workflow. Training costs would need their own accounting too." +msgstr "" +"在這些案例上,要統計的是完整、獨立驗證過的匹配成果。給每個模型相同的候選數量或編譯次數預算,可以比較搜尋品質。記錄總耗時和總成本,包括編譯,才能知道這種品質是否轉化成了高效的工作流程。訓練成本也要單獨計算。" + +#: website/public/blog/reverse-engineering-models/index.html:706 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Both views matter because a cheaper proposal can become an expensive " +"workflow if it causes more uninformative compiles. Conversely, a slower " +"model may pay for itself by finding a useful experiment sooner. The " +"comparison should capture those costs." +msgstr "" +"兩種角度都重要。一個便宜的提議,如果導致大量無效編譯,整個工作流程仍可能很貴。反過來,較慢的模型如果更早找到有價值的實驗,也可能更划算。對照實驗應當反映這些成本。" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:712 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"Counting accepted results also keeps intermediate progress in perspective. " +"One TH09 {ph0}replay-save candidate{ph1} looked promising because the " +"compiled function had the expected size, but a full comparison still found " +"substantial differences. Changes in how the compiler arranges instructions " +"can also make a candidate look closer without resolving the underlying " +"problem. Such diagnostics can guide the next experiment, but I would " +"validate any reward for \"getting closer\" against the full acceptance " +"check." +msgstr "" +"只統計透過驗收的結果,也能幫助我們合理看待中間進展。TH09 " +"的一個{ph0}錄影儲存候選方案{ph1}看起來很有希望,因為編譯後函式的大小符合預期,但完整比較仍發現大量差異。編譯器改變指令排列,也可能讓候選原始碼看起來更接近,卻沒有解決根本問題。這些診斷可以指導下一步,但若要獎勵“變得更接近”,我會先對照完整驗收檢查,確認這種獎勵有效。" + +#: website/public/blog/reverse-engineering-models/index.html:727 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"I would be interested in the pattern across these results. If a specialist " +"does well within a familiar compiler family, does that advantage survive a " +"toolchain change? And once both models have good retrieval, how much does " +"training still add? The answers would help us decide where each kind of " +"model is most useful." +msgstr "" +"我想看這些結果呈現出什麼規律。如果專用模型在熟悉的編譯器上表現很好,換了工具鏈後,這種優勢還在嗎?當雙方都擁有良好的檢索能力時,訓練還能增加多少價值?這些答案能幫助我們決定,每類模型最適合用在哪裡。" + +#: website/public/blog/reverse-engineering-models/index.html:736 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "What kind of agent does this suggest?" +msgstr "這意味著怎樣的 agent?" + +#: website/public/blog/reverse-engineering-models/index.html:737 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"If the models turn out to help at different stages, a useful arrangement " +"might be a broad agent with access to a specialist. Once a task becomes a " +"familiar compiler search, it could ask the specialist for candidates. If the" +" results stop making sense, the broader agent could return to the target " +"evidence or investigate the measurement itself." +msgstr "" +"如果不同模型在不同階段各有所長,一種有價值的安排可能是:讓能力全面的 agent " +"可以呼叫專用模型。當任務變成一種熟悉的編譯器搜尋時,它可以請專用模型提出候選方案。如果結果開始說不通,通用 agent " +"可以回頭檢查目標證據,或者調查測量本身。" + +#: website/public/blog/reverse-engineering-models/index.html:745 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"In that arrangement, specialization becomes a tool the agent can choose as " +"the investigation develops. The agent keeps the freedom to change direction " +"that made the earlier breakthroughs possible." +msgstr "" +"在這樣的安排中,專用模型成為 agent 隨著調查進展可以選擇的工具。agent 仍然擁有改變方向的自由,而這正是前面那些突破發生的重要條件。" + +#: website/public/blog/reverse-engineering-models/index.html:750 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"This follows naturally from the industrial shift I described in the previous" +" essay. Being able to run many more experiments changes how we organize the " +"work. It also gives us a reason to ask which decisions need broad judgment " +"and which improve through repeated experience with a particular craft." +msgstr "" +"這自然延續了上一篇文章中談到的工業化轉變。能夠開展更多實驗,會改變我們組織工作的方式,也讓我們有理由追問:哪些決策需要全面的判斷,哪些可以透過反覆積累某項具體技藝來改善?" + +#: website/public/blog/reverse-engineering-models/index.html:757 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"For now, the strongest general model has earned its place in my workflow by " +"opening problems I had left unresolved. Those successes are what make me " +"want to examine the work more closely: how much depended on the model's " +"breadth, and how much could be handled by a model trained in this particular" +" kind of reconstruction?" +msgstr "" +"目前,最強的通用模型解決了我過去沒能解決的問題,因此在我的工作流程中佔據了一席之地。正是這些成功,讓我想更仔細地研究過程:有多少依賴模型能力的廣度?又有多少可以交給專門學習這類重建的模型?" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:765 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}The repositories give us a way to test the question.{ph1} I would like " +"to use that record to build the comparison and see what we learn." +msgstr "{ph0}這些程式碼倉庫讓我們有機會驗證這個問題。{ph1} 我想利用這些記錄建立對照實驗,看看我們能學到什麼。" + +#: website/public/blog/reverse-engineering-models/index.html:775 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Evidence and model attribution" +msgstr "證據與模型歸屬" + +#: website/public/blog/reverse-engineering-models/index.html:783 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The examples describe historical function-level comparisons recorded in the " +"linked commits. Whole-game runtime checks are separate milestones. Source " +"and matching records were reviewed on 13 October 2026." +msgstr "" +"這些例子來自連結中的提交中記錄的歷史函式級比較。整款遊戲的執行時檢查屬於另一個里程碑。相關原始碼與匹配記錄核查於 2026 年 10 月 13 日。" + +#. {ph0}: gpt-dots +#. {ph1}: gpt-web +#: website/public/blog/reverse-engineering-models/index.html:789 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The TH09 label {ph0} identifies GPT-6-Astra. {ph1} changed with the model " +"used at the time, so that label alone does not identify an individual run. " +"Explicit model names in the other cited commits establish their recorded " +"attribution; the histories do not contain uniform per-run cost or effort " +"measurements." +msgstr "" +"TH09 中的標籤 {ph0} 對應 GPT-6-Astra。{ph1} " +"會隨當時使用的模型變化,因此僅憑這個標籤無法確定某次執行的具體模型。其他引用提交中的明確模型名,提供了對應的歸屬記錄;這些歷史記錄並沒有統一的單次執行成本或投入統計。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#: website/public/blog/reverse-engineering-models/index.html:798 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 temporary lifetimes:{ph1} the {ph2}earlier context review{ph3} and" +" {ph4}complete cold reconstruction{ph5}." +msgstr "{ph0}TH09 臨時值生命週期:{ph1}{ph2}早期上下文檢查{ph3}與{ph4}完整的乾淨重建{ph5}。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:810 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}TH09 Front callback:{ph1} {ph2}non-exact diagnostic regions{ph3}, " +"{ph4}Astra's new graph{ph5} and its {ph6}accepted recompile replay{ph7}." +msgstr "" +"{ph0}TH09 Front 回呼:{ph1}{ph2}未匹配的診斷區域{ph3}、{ph4}Astra " +"提出的新控制流圖{ph5}與{ph6}透過驗收的重新編譯檢查{ph7}。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:826 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Compiler knowledge:{ph1} {ph2}TH095 identifier-bucket reuse{ph3}, " +"{ph4}TH04 player source and linker order{ph5} and {ph6}Luna's TH09 enemy-" +"spawn closure{ph7}." +msgstr "" +"{ph0}編譯器知識:{ph1}{ph2}TH095 識別符號分桶規律的複用{ph3}、{ph4}TH04 " +"玩家原始碼與連結順序{ph5}、{ph6}Luna 完成的 TH09 敵人生成函式匹配{ph7}。" + +#. {ph0}: +#. {ph1}: +#. {ph2}: +#. {ph3}: +#. {ph4}: +#. {ph5}: +#. {ph6}: +#. {ph7}: +#: website/public/blog/reverse-engineering-models/index.html:842 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Checks and diagnostics:{ph1} {ph2}TH08 floating-literal audit{ph3}, " +"{ph4}TH08 numerical investigation{ph5} and {ph6}TH09 replay-save " +"reconstruction{ph7}." +msgstr "" +"{ph0}檢查與診斷:{ph1}{ph2}TH08 浮點常量審計{ph3}、{ph4}TH08 數值問題調查{ph5}、{ph6}TH09 " +"錄影儲存重建{ph7}。" + +#: website/public/blog/reverse-engineering-models/index.html:859 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"The proposed specialist and RL comparisons are future experiments. The " +"project histories motivate them; no trained specialist was evaluated for " +"this essay." +msgstr "文中提出的專用模型與 RL 對照,屬於未來實驗。專案歷史為這些想法提供了依據;本文尚未評估經過訓練的專用模型。" + +#: website/public/blog/reverse-engineering-models/index.html:6 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Does reverse engineering need a bigger model? | REA" +msgstr "逆向工程需要更大的模型嗎? | REA" + +#: website/public/blog/reverse-engineering-models/index.html:7 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"What Touhou reconstruction taught me about general models, specialist models" +" and learning to propose better hypotheses from compiler feedback." +msgstr "東方重建讓我如何思考通用模型、專用模型,以及怎樣從編譯器回饋中學會提出更好的假設。" + +#: website/public/blog/reverse-engineering-models/index.html:240 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "On this page" +msgstr "在本頁" + +#: website/public/blog/reverse-engineering-models/index.html:253 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Models and reverse engineering essay" +msgstr "模型與逆向工程隨筆" + +#: website/public/blog/reverse-engineering-models/index.html:491 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Selected reconstruction experiments" +msgstr "重建實驗選例" + +#: website/public/blog/reverse-engineering-models/index.html:883 +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "Back to top" +msgstr "回到頂部" + +#. {ph0}: +#. {ph1}: +#: website/public/blog/reverse-engineering-models/index.html:776 +#, python-brace-format +msgctxt "page:blog/reverse-engineering-models/index.html" +msgid "" +"{ph0}Detailed evidence notes{ph1} include the recorded comparisons and " +"experiment context." +msgstr "{ph0}詳細證據記錄{ph1}包含歷史比較結果與實驗背景。" + +#~ msgctxt "page:blog/index.html" +#~ msgid "By N0zoM1z0 · 13 October 2026 · Draft for review" +#~ msgstr "作者 N0zoM1z0 · 2026 年 10 月 13 日 · 待審草稿" + #~ msgctxt "page:index.html" #~ msgid "Setup guide" #~ msgstr "安裝指南" diff --git a/website/public/blog/index.html b/website/public/blog/index.html index 3ad338db8..a89e27807 100644 --- a/website/public/blog/index.html +++ b/website/public/blog/index.html @@ -196,6 +196,20 @@

Thoughts on reverse engineering.

+
+

Model specialization
Essay

+
+

Does reverse engineering need a bigger model?

+

+ What Touhou reconstruction suggests about general models, + specialist models and learning from compiler feedback. +

+ Read the article +

By N0zoM1z0 · 13 October 2026

+
+

Game reconstruction
Essay

diff --git a/website/public/blog/reverse-engineering-models/index.html b/website/public/blog/reverse-engineering-models/index.html new file mode 100644 index 000000000..a92f9f84f --- /dev/null +++ b/website/public/blog/reverse-engineering-models/index.html @@ -0,0 +1,888 @@ + + + + + + Does reverse engineering need a bigger model? | REA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +

Essay

+

Does reverse engineering need a bigger model?

+

By N0zoM1z0 · 13 October 2026

+
+

Takeaway

+
    +
  • + Model capability changes the hypotheses an agent can + find. + Later sessions have solved problems that earlier work left + unresolved. +
  • +
  • + A familiar compiler gives specialization something concrete to + learn. + Some exact matches depend on narrow, reusable source patterns. +
  • +
  • + Give repository knowledge a fair comparison. + A smaller model with good retrieval may already know enough to + make progress. +
  • +
  • + Train the next useful experiment, and test its oracle. + The value of feedback depends on what the checker actually + verifies. +
  • +
  • + Measure accepted reconstruction against time and cost. + That is the result I want from the whole agent. +
  • +
+
+
+
+ +
+
+

What better models changed

+

+ Since August 2026, I have been exploring how much reverse + engineering an agent can carry out with access to a program and a + way to check its work. Most of my experience comes from + reconstructing games, especially Touhou. As I have changed models, + the repositories have kept a record of what each session managed + to recover. +

+

+ Much of that work aims at exact reconstruction: we compile the + maintained source under a pinned historical toolchain and check + whether it reproduces the target function. When a later model + succeeds where earlier work stalled, the source changes show what + made that progress possible. +

+

The temporary values had to stay alive together

+

+ Much of a TH09 attack function's logic had already been + reconstructed, but the compiler still stored temporary results + differently from the original. The remaining problem was how long + those results needed to stay alive and when their storage could be + reused. +

+

+ A + GPT-6-Sol checkpoint + recorded this mismatch after testing several ordinary source + arrangements. When + GPT-6.1-Sol returned to the problem, it found a useful hypothesis about how long those temporary + values needed to stay alive. +

+

+ The function produced temporary results and copied them into + animation positions. In C++, a temporary result stays alive until + the expression using it finishes. Grouping the real operations + into one expression kept those results alive together, so the + compiler could no longer reuse the same storage for all of them. +

+

+ One result still shared storage with a value used later for + collision checks. Giving that value its own lifetime resolved the + remaining overlap. After several targeted experiments, + a clean rebuild confirmed that the full function + matched. +

+

+ What interests me is how the discovery and the tests worked + together. The lifetime hypothesis gave the agent a new direction; + compiler feedback helped it refine that hypothesis into a source + arrangement that matched. +

+

A different control-flow graph

+

+ A second TH09 function shows why that new direction can matter. + Here, the obstacle was how several branches shared their final + work. + GPT-6.1-Sol's earlier work + got parts of the function to match, but the branches still joined + up differently from the original. +

+

+ GPT-6-Astra changed the surrounding control-flow graph. The main paths now led to a shared final update and return. In + that source structure, the compiler combined the branches in the + same way as the original. The complete function matched, and a + separate rebuild check confirmed it. +

+

+ Changing the representation opened a more productive search + space. + Both cases give me a reason to take general model capability + seriously: an agent can keep trying local variations for a long + time before finding a better way to express the surrounding work. +

+

+ At the same time, the later sessions started with earlier source + and recorded failures. That accumulated work was part of their + advantage. The history lets us inspect the discoveries and their + checks; a controlled comparison would help separate the effect of + the model from the experience it inherited. +

+

+ This is where the question becomes interesting to me. Some of the + progress came from finding a new representation, while much of the + remaining work involved testing source forms against a familiar + compiler. How much needs broad reasoning ability, and how much + could a model learn through repeated experience with that compiler + and code? +

+
+
+

Why might a specialist do well?

+

+ Touhou gives us a concrete reason to expect that experience to + help. Much of the game code comes from the same author, ZUN, so + recurring habits are a reasonable starting assumption. The + repositories back that up with useful examples: related loops and + helper arrangements have supplied hypotheses across games. +

+

+ Those source patterns become more specific when we include the + compiler. Under a particular version and set of options, small + changes in source can produce repeatable differences in machine + code. Some of those differences are surprisingly obscure. +

+

+ In TH095, for example, + even the name used for a local variable could change where + VC7.1 stored it. Moving the declaration alone did not solve the layout, but an + earlier background function had revealed a naming pattern that + affected the compiler's choice. That gave us a more promising + hypothesis for + the reconstruction of Supervisor::LoadDat. +

+

+ Reusing that pattern for the file-size variable produced the + required layout without adding storage. The full function then + matched. +

+

+ This is the sort of narrow detail a general model may not know + when it arrives. A specialist trained on this compiler could + encounter many such cases and learn which source variations are + worth testing first. +

+

+ The opportunity is especially clear in final matching problems + where we already understand the behavior. We are then asking which + ordinary source form this compiler turns into the observed + instructions. Specialization could help the model propose those + forms more efficiently, while the target still determines which + hypotheses survive. +

+

+ The useful patterns would have to retain their context, though. + TH08 uses an earlier Visual C++ version than TH095 and TH09. TH04 + uses a different DOS-era compiler, and its + player reconstruction + needed different hypotheses about source patterns and how the + compiled code was combined into an executable. Shared authorship + gives us a prior, but each target tells us whether it applies. + Distinguishing those contexts is part of what a specialist would + need to learn. +

+
+
+

Where should that experience live?

+

+ Before deciding to teach those patterns through model training, I + would look at the knowledge we already keep in the repository. In + the + previous essay, I wrote + about it becoming the project's working memory. That memory + includes compiler lessons, along with the source and failed + experiments that made them useful. +

+

+ By retrieving that record, an agent can start with a known result + and inspect how we reached it. It can also avoid alternatives that + have already failed in the same context. The starting point + improves without changing the model's weights. +

+

+ When reconstructing TH09's enemy-spawn function, a + GPT-6-Luna-max session + drew a hypothesis from TH08's corresponding source family. That + earlier source suggested how to structure the loop and handle + failures within it. TH09's own evidence supplied the game-specific + details, and clean rebuilds confirmed the complete match. +

+

+ "The model did not know that compiler quirk" and "the model + could not use it" are different problems. + Retrieval may solve the first, but turning that fact into a useful + candidate still takes work. And if the candidate fails, the model + must decide what the result means for its next attempt. Knowing + the relevant pattern is only the beginning of that process. +

+

+ For that reason, I would include a smaller general model with good + retrieval in any comparison. Giving it the same library of + experience would help us identify what training adds: better + candidate generation, better decisions after feedback, or both. +

+
+
+

Learning the next useful experiment

+

+ Those decisions after feedback are what I would most like to + study. In agentic reconstruction, the model proposes an + explanation and tests it against the program. Even when the + candidate fails, the result can narrow the remaining possibilities + and suggest a more useful next experiment. +

+

+ Consider the temporary-results example again. Its final source + shows the arrangement that worked, but the route to that source + contains more information. Each of the following experiments + helped identify what still needed to change. +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ExperimentWhat its result taught us
Try a different way to copy the results + The copy code changes, but the function still differs. +
Use the returned values directly + Copying follows the original pattern, but temporary + storage still differs. +
Keep the temporary results alive together + They get separate storage, but one still overlaps a value + used later for collision checks. +
Keep the collision-check value separateA clean rebuild confirms the complete match.
+
+

+ Selected experiments from the attack-function reconstruction + above, grouped by what they taught us. +

+

+ A training record that keeps this sequence can teach more than the + final source alone. It connects each proposed change to an + observed result and the next decision. Keeping ineffective + variations matters too: they tell a later agent which hypotheses + have already been tested in that context. +

+

+ I would want the model to learn how to use feedback. + A neutral result is a reason to reconsider the variation; a + changed mismatch may point to another cause. When local edits stop + being informative, the agent should be able to revisit the source + representation or inspect the evidence again. +

+

+ Learning to make those choices requires autonomy. Sometimes the + useful next step is inspecting another caller rather than + compiling another edit. A rigid sequence of required rewrites + would remove that choice, along with part of the behavior we want + the model to learn. +

+
+
+

Why RE is interesting for reinforcement learning

+

+ Bounded reconstruction gives us a practical environment for + studying these choices. Once the target and compiler are pinned, + many source experiments produce quick, repeatable feedback. The + agent can compile a candidate, inspect the mismatch and use that + observation to choose its next step. +

+

+ Reinforcement learning could train that decision-making process + through the feedback it receives. A candidate accepted by a + defined check gives us a concrete outcome, while the sequence of + attempts lets us observe how much work it took to reach it. +

+

+ There is already research supporting this direction. + LLM4Decompile + studies models specialized for decompilation. + AutoDecompiler + trains multi-turn refinement using compiler and execution + feedback. Their studies focus on functional recovery. For this + work, I would use them as a starting point for the related task of + finding source that matches a historical compiler's output. +

+

+ To reach such a well-defined task, though, we may first need to + establish what a function owns or devise a new runtime + measurement. In TH08, for example, a + collision difference led back to how the original program + handled floating-point calculations. Before the agent could test a useful correction, it had to work + out what to measure. +

+

+ This suggests another role for a broadly capable model: helping + make the problem checkable in the first place. Once that check + exists, we can investigate how far a learned search policy can get + with it. +

+
+
+

When the oracle is wrong

+

+ Once we train against that check, its coverage becomes part of + what the model learns. I call the reference or checker an oracle. + Even if it gives a repeatable answer, we still need to understand + what that answer covers. +

+

+ TH08 showed how much can hide outside that coverage. Some + reconstructed functions passed their exact comparisons with wrong + floating constants. The comparator adjusted relocated addresses + before checking instructions, but it checked the values behind + those addresses only when they had been explicitly recorded for + verification. Other literal references could pass without their + values being examined. +

+

+ To close that gap, a + wider audit + found incorrect constants in functions that had already been + accepted. In one calculation, the reconstructed source added + 1.0f where the original added 32.0f. +

+

+ A learner rewarded by the old check could learn to produce the + wrong reconstruction. + We had not trained an RL model against this oracle; the observed + failure was in the check itself. But using that check as a reward + would have made the same blind spot part of the learning + environment. +

+

+ A functional test can have a similar blind spot. + Differential-fuzzing research on LLM decompilers + has found behavior differences beyond the supplied tests. Passing + those tests therefore needs to be read in terms of the cases they + exercise, just as an instruction match needs to be read in terms + of the bytes and data it checks. +

+

+ Before using either kind of check as a reward, I would test it + with deliberate failures. I would also keep final acceptance + outside the candidate's editable source, so the model has to + satisfy the check through its reconstruction. Otherwise, something + like a byte array copied from the target could satisfy a naive + score without recovering useful source. +

+

+ Improving the learner and improving its oracle belong to the + same research problem. + As the learner gets better at optimizing the feedback we give it, + understanding that feedback becomes more important too. +

+
+
+

A comparison worth running

+

+ With those checks in place, I would start the comparison on a + fixed VC7.1 task family. First, I would establish baselines for a + strong general model and a smaller one. Adding repository + knowledge to the smaller model would show what retrieval changes. + From there, supervised specialization and an RL-trained version + would let us examine what training adds. +

+

+ To make those comparisons informative, each model would receive + the same target evidence and tools. For the training-specific + comparisons, I would keep the base model and available knowledge + fixed as well. Repeated trials would help distinguish a reliable + search strategy from a lucky candidate. +

+

+ I would then separate two starting conditions: reconstructing a + function from its instructions, and closing the last few + differences in maintained source. A specialist might be excellent + at the second task while a general model does much of the work + needed to reach it. Measuring them separately would reveal that + division of work. +

+

+ Both tasks need genuinely held-out examples. Because related + Touhou games share engine code, holding out a game's name would + still allow nearly identical functions to appear in training. I + would instead hold out source families and keep their accepted + answers out of both training and retrieval. +

+

+ On those examples, the outcome would be complete, independently + validated matches. Giving each model the same candidate or compile + budget would help compare search quality. Measuring elapsed time + and total cost, including compilation, would tell us whether that + quality produces an efficient workflow. Training costs would need + their own accounting too. +

+

+ Both views matter because a cheaper proposal can become an + expensive workflow if it causes more uninformative compiles. + Conversely, a slower model may pay for itself by finding a useful + experiment sooner. The comparison should capture those costs. +

+

+ Counting accepted results also keeps intermediate progress in + perspective. One TH09 + replay-save candidate + looked promising because the compiled function had the expected + size, but a full comparison still found substantial differences. + Changes in how the compiler arranges instructions can also make a + candidate look closer without resolving the underlying problem. + Such diagnostics can guide the next experiment, but I would + validate any reward for "getting closer" against the full + acceptance check. +

+

+ I would be interested in the pattern across these results. If a + specialist does well within a familiar compiler family, does that + advantage survive a toolchain change? And once both models have + good retrieval, how much does training still add? The answers + would help us decide where each kind of model is most useful. +

+
+
+

What kind of agent does this suggest?

+

+ If the models turn out to help at different stages, a useful + arrangement might be a broad agent with access to a specialist. + Once a task becomes a familiar compiler search, it could ask the + specialist for candidates. If the results stop making sense, the + broader agent could return to the target evidence or investigate + the measurement itself. +

+

+ In that arrangement, specialization becomes a tool the agent can + choose as the investigation develops. The agent keeps the freedom + to change direction that made the earlier breakthroughs possible. +

+

+ This follows naturally from the industrial shift I described in + the previous essay. Being able to run many more experiments + changes how we organize the work. It also gives us a reason to ask + which decisions need broad judgment and which improve through + repeated experience with a particular craft. +

+

+ For now, the strongest general model has earned its place in my + workflow by opening problems I had left unresolved. Those + successes are what make me want to examine the work more closely: + how much depended on the model's breadth, and how much could be + handled by a model trained in this particular kind of + reconstruction? +

+

+ The repositories give us a way to test the question. + I would like to use that record to build the comparison and see + what we learn. +

+
+
+
+ Evidence and model attribution +

+ Detailed evidence notes + include the recorded comparisons and experiment context. +

+

+ The examples describe historical function-level comparisons + recorded in the linked commits. Whole-game runtime checks are + separate milestones. Source and matching records were reviewed + on 13 October 2026. +

+

+ The TH09 label gpt-dots identifies GPT-6-Astra. + gpt-web changed with the model used at the time, so + that label alone does not identify an individual run. Explicit + model names in the other cited commits establish their recorded + attribution; the histories do not contain uniform per-run cost + or effort measurements. +

+ +

+ The proposed specialist and RL comparisons are future + experiments. The project histories motivate them; no trained + specialist was evaluated for this essay. +

+
+
+
+
+
+ + + +

+ + Top + + + + diff --git a/website/templates/header.html.tmpl b/website/templates/header.html.tmpl index 6ac759580..4e8d0caaa 100644 --- a/website/templates/header.html.tmpl +++ b/website/templates/header.html.tmpl @@ -7,7 +7,7 @@ >
- $language_picker +$language_picker