Skip to content

PR #77 cleanup: restore line endings, drop private paths, apply the media input policy - #88

Draft
Hao0321 wants to merge 6 commits into
feat/latest-agent-engine-20261001from
security/pr77-cleanup
Draft

Hao0321 wants to merge 6 commits into
feat/latest-agent-engine-20261001from
security/pr77-cleanup

Conversation

@Hao0321

@Hao0321 Hao0321 commented Oct 6, 2026

Copy link
Copy Markdown
Owner

What changed

This targets the branch behind #77 (feat/latest-agent-engine-20261001), not main. It fixes the mechanical items from the #77 security review. There is one commit per item, so each can be checked on its own.

  1. 7d59575 chore: restore original line endings. Share 2026-10-05 Motion source and contributor baseline (development) #77 converted whole files between LF and CRLF. For example, src-tauri/src/main.rs showed +12,619/−11,890 lines, of which only +797/−68 are real changes. That hid the real changes in CODEOWNERS paths and breaks the * -text rule in AGENTS.md.
    • Files: 63 files go back to their merge-base convention. Two files that were mixed at the base keep their base endings on unchanged lines. New files use LF, like their directories.
    • Content: git diff --ignore-cr-at-eol 8993cf8 7d59575 is empty.
    • Result: against the merge base, the raw diff stat now equals the line-ending-insensitive one, file by file: 69,585+/2,267−.
    • Exception: public/fonts/static-face-provenance.json stays CRLF. public/fonts/editkin-open-fonts.json pins those exact bytes, and that file's own hash is pinned by src/generated/fontEmMetrics.json and a Rust test.
  2. 69d5567 chore: refresh source manifest rows for restored line endings. PUBLIC_SOURCE_MANIFEST.json changes only the bytes/sha256 of rows whose files changed, plus a row for the new test in item 3.
  3. 41a7ab1 fix(scripts): take private media and skill names from explicit inputs. These scripts hard-coded private media folders, file names and a personal Skill name. Each now reads its input from a variable and fails before writing anything if the variable is unset. With the same inputs, the scripts run the same checks.
    • reference-motion-template-render-gate.ts: EDITKIN_REFERENCE_MOTION_OWNED_SOURCES and EDITKIN_REFERENCE_MOTION_OWNED_MUSIC
    • music-mv-product-gate.ts --real-footage: EDITKIN_MUSIC_MV_REAL_FOOTAGE_PROJECT
    • autopilot-integration-gate.ts: EDITKIN_PERSONAL_SKILL_DEPENDENCIES
    • mesh3d-mcp-journey.ts: writes its evidence under its evidence directory, and uses EDITKIN_WORKSPACE (default: repo root)
  4. 318a0a7 fix(media): apply the local media input policy to mesh textures and Electron import. Share 2026-10-05 Motion source and contributor baseline (development) #77 added mediaUtilityInputPolicy.ts (-protocol_whitelist file plus -format_whitelist) but did not use it for the new mesh-texture probe and decoder or for the Electron import probe. It does now, through optional input options on probeMedia/inspectMedia. Existing callers are unchanged, and the encoder's pipe:0 input is not affected.
  5. 2d5aeb7 fix(scripts): require an explicit destination for skill exports. export-module-registry.ts and export-motion-language.ts no longer write into ~/.codex/... by default. They need an output path or EDITKIN_VIDEO_AUTOPILOT_SKILL_ROOT, and otherwise exit 1 without writing.

User journey and platform

  • Editing, preview and export are unchanged.
  • Mesh 3D textures and Electron imports now refuse HLS playlists and concat lists, as the policy already did for conversion.
  • The owner gate scripts need their inputs set explicitly.

Validation

  • npm run typecheck, npm run build: exit 0.
  • npm run source:verify:self-test: GREEN.
  • npm run source:scan and npm run source:verify: GREEN, 1709 files.
  • Targeted vitest: 7 files, 47 tests pass. The new src/render/mesh3dRender.inputPolicy.test.ts and the added cases each fail without their fix.
  • Full npm test, before vs after: the same 81 test files fail (the branch's existing failures, mostly missing generated render fonts). Passing went from 380 to 381 files, and 4 more tests pass; those are the new tests. The failing file and test lists are identical.
  • FFmpeg 6.1.1, by hand:
    • mp4, png, jpg and webp open with the policy.
    • An HLS playlist and an ffconcat list are rejected; without the policy they open.
    • renderMesh3dVideo rendered mp4, jpg and png textures and rejected the playlist.
  • Not run: Rust builds. scripts/architecture-check.ts fails both before and after this PR, with the same findings that Share 2026-10-05 Motion source and contributor baseline (development) #77 introduced.

Security and provenance

  • Dependencies, network, process execution: none added.
  • File writes: fewer. The skill export scripts no longer write outside the repo by default, and the gate scripts no longer contain private paths.
  • Secrets and private footage: none included.

Decisions for the owner that this PR leaves alone:

  • the force-added public/fonts/render/*.ttf
  • the new three/opentype.js dependencies
  • the PowerShell/DPAPI key code in src/security/userCommitSigningKey.ts
  • the 19 CodeQL alerts and the existing failing tests on this branch

A bug that already exists in #77, not fixed here: when a mesh texture fails, renderMesh3dVideo sends the FFmpeg encoder SIGTERM but never closes its stdin, so one FFmpeg process is left behind per failed render. Calling encoder.child.stdin.destroy() before kill() should fix it.

DCO

Every commit has a Signed-off-by: trailer.

🤖 Generated with Claude Code

https://claude.ai/code/session_01YQbUWKu73ka7dZ58vWVzgY


Generated by Claude Code

Hao0321 and others added 6 commits October 6, 2026 06:36
The repository sets `* -text` and the source manifest hashes exact
bytes, so whole-file EOL conversion turns small edits into full-file
rewrites. Compared with the merge base, this branch had converted 36 LF
files to CRLF or mixed endings, rewritten the mostly-CRLF
source-test-exclusions.json as LF, mixed LF lines into two CRLF files,
and added 22 new text files with CRLF or mixed endings next to LF files.

Each file changed by the branch that existed at the merge base now uses
the merge-base convention again. For the two files that were already
mixed at the merge base, lines unchanged from the base keep their base
ending and new lines use the base majority (CRLF). New files use LF like
their directories, except public/fonts/static-face-provenance.json: it
now carries the generator's CRLF bytes that the existing
staticFaceProvenance record in editkin-open-fonts.json already pins
(sha256 5e225aa3...). Re-pinning that record instead would change the
font manifest hash that src/generated/fontEmMetrics.json and the
desktop runtime verify.

Only CR bytes before LF changed: `git diff --ignore-cr-at-eol` against
the previous commit is empty, and the raw diff stat against the merge
base now equals the EOL-insensitive one. The source manifest rows for
these files are refreshed in the next commit.

Signed-off-by: Hao0321 <126182090+Hao0321@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YQbUWKu73ka7dZ58vWVzgY
This branch keeps PUBLIC_SOURCE_MANIFEST.json as an exact snapshot of
the tree (`npm run source:verify` is green at the branch head), and the
previous commit changed the bytes of 63 files by restoring their line
endings. Update only the bytes and sha256 values of those 63 rows so the
snapshot verification stays green; no other row changes and the
manifest is not regenerated.

It is a separate commit because the line-ending commit is kept free of
any content change (`git diff --ignore-cr-at-eol` is empty there).

Signed-off-by: Hao0321 <126182090+Hao0321@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YQbUWKu73ka7dZ58vWVzgY
Several gate scripts added on this branch named the maintainer's private
footage folders, camera and music file names, a private benchmark
project, the private monorepo layout and a personal Skill id. Publishing
those leaks local layout and library contents, and the scripts cannot
run from a community checkout anyway.

- reference-motion-template-render-gate: the four owned clips and the
  music file come from EDITKIN_REFERENCE_MOTION_OWNED_SOURCES (ordered,
  path-delimiter separated) and EDITKIN_REFERENCE_MOTION_OWNED_MUSIC;
  asset names use the supplied file names and the music receipt no
  longer describes the private library.
- music-mv-product-gate: --real-footage reads the project named by
  EDITKIN_MUSIC_MV_REAL_FOOTAGE_PROJECT; the report wording is neutral.
- autopilot-integration-gate: personal Skill ids come from
  EDITKIN_PERSONAL_SKILL_DEPENDENCIES (comma separated, empty when
  none); the published ids stay pinned in the script.
- mesh3d-mcp-journey: write the render inside the evidence directory and
  use EDITKIN_WORKSPACE (default: repository root) instead of assuming
  a private monorepo two levels up.
- export-module-registry / export-motion-language: record the public
  script path as the generator.

Missing inputs fail closed before any evidence is written, with a
Traditional Chinese message naming the variable. When the same inputs
are supplied, every gate performs the same checks as before. The
source manifest rows for the six scripts are refreshed.

Signed-off-by: Hao0321 <126182090+Hao0321@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YQbUWKu73ka7dZ58vWVzgY
…lectron import

This branch added mediaUtilityInputPolicy (-format_whitelist of
self-contained demuxers plus -protocol_whitelist file) for conversion
and audio gain, but two new paths still handed project or user media to
FFmpeg without it: the mesh 3D texture probe and decoder, and the
Electron import probe. A file named like ordinary media can then be
opened as HLS, concat or image2 and pull in secondary files or other
protocols.

- probeMedia and inspectMedia accept optional input options placed
  before the input path; existing callers are unchanged.
- renderMesh3dVideo probes and decodes each bound texture with the
  policy. The raw-video encoder input (pipe:0) is Editkin's own stream
  and keeps its options, so lavfi/pipe inputs are not affected.
- The Electron import service (file picker and path import) probes each
  picked file with the policy; all extensions it accepts map to
  whitelisted demuxers, and JPEG keeps the forced jpeg_pipe reader.

Tests record the real argv through a Node stand-in for FFmpeg, so they
run without FFmpeg; each fails without its fix. A manual run with
FFmpeg 6.1.1 opened mp4/png/jpg/webp with the policy and rejected an
HLS playlist and an ffconcat list that open without it. The source
manifest rows are refreshed and the new test file is recorded.

Signed-off-by: Hao0321 <126182090+Hao0321@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YQbUWKu73ka7dZ58vWVzgY
export-module-registry and export-motion-language wrote into
~/.codex/skills/video-autopilot/references/ whenever no output path was
given, so a plain run modified a directory outside the repository that
belongs to another tool. The override variable also lacked the EDITKIN_
prefix.

Both scripts now take the destination from the output path argument or
from EDITKIN_VIDEO_AUTOPILOT_SKILL_ROOT (<root>/references/<file>). With
neither, they print a Traditional Chinese message and exit 1 without
writing anything. --check uses the same explicit destination. The
unused home-directory default constant is removed. The source manifest
rows for both scripts are refreshed.

Signed-off-by: Hao0321 <126182090+Hao0321@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YQbUWKu73ka7dZ58vWVzgY
On GitHub's Windows runners tmpdir() returns an 8.3 short path
(C:\Users\RUNNER~1\...). The import boundary requires every ancestor
of a selected file to equal its realpath, so every fixture-based case
in this file failed there with the ancestor-realpath error. Create the
fixture root under realpath(tmpdir()) instead.

Signed-off-by: Hao0321 <126182090+Hao0321@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YQbUWKu73ka7dZ58vWVzgY

Hao0321 commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner Author

CI on this PR, compared with its base #77 at 8993cf8 (which fails the same checks):

  • Source (ubuntu|windows|macos-latest) fail in npm test on 2d5aeb7 and 0713aba, the same way the base does.
    • Most failures are ENOENT on gitignored generated fonts under public/fonts/render/ (for example EditkinFace-bebas-neue-400.ttf).
    • Ubuntu: 208 error annotations on both runs, and no failing test file that the base lacks.
    • Windows at 0713aba: 53 failing files, against 55 on the base. None of them is new.
    • These suites need the generated render fonts or registration in source-test-exclusions.json. That is an owner decision for Share 2026-10-05 Motion source and contributor baseline (development) #77, outside this PR's scope.
    • A re-run cannot change this, because the files are not in the checkout.
  • Linux GTK desktop fails in "Exercise the native editor" at native-text-input: [data-testid="caption-advanced"] .number-field input [1].
  • Fixed on Windows in 0713aba: src/desktop/electronWorkflowIpc.test.ts failed on the base with "媒體祖先 realpath 不是原本本機目錄".
    • Cause: the runner's tmpdir() is an 8.3 short path (RUNNER~1), and the import boundary compares every ancestor with its realpath.
    • The fixture root is now created under realpath(tmpdir()).
    • Verified on the Windows run: that error went from 8 occurrences to 0, and the file no longer fails.

Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant