Skip to content

feat: Real platform detection + unified version system#426

Merged
jsavin merged 5 commits into
developfrom
feature/env-version
Feb 15, 2026
Merged

feat: Real platform detection + unified version system#426
jsavin merged 5 commits into
developfrom
feature/env-version

Conversation

@jsavin

@jsavin jsavin commented Feb 15, 2026

Copy link
Copy Markdown
Owner

Summary

  • Fix headless initenvironment() to detect actual platform via #ifdef __APPLE__/__linux__/_WIN32 instead of setting all flags to false. On macOS, queries real OS version via sw_vers.
  • Add three new system.environment flags: isHeadless, isPosix, isLinux
  • Unify version system: Frontier.version() returns product version derived from git tags (CLI major + 10), preserving backward compat with date.versionLessThan() checks against legacy 7.x/10.x versions
  • Add Frontier.cliVersion() kernel verb returning the git-derived CLI distribution version
  • Add tools/derive_product_version.sh for Makefile version derivation

Version mapping examples

Git tag Frontier.version() Frontier.cliVersion()
v1.0.0-alpha.6 11.0a6 v1.0.0-alpha.6
v1.0.0-beta.3 11.0b3 v1.0.0-beta.3
v1.2.3 11.2.3 v1.2.3

system.environment changes (macOS)

Flag Before After
isMac false true
isCarbon false true
isHeadless (missing) true
isPosix (missing) true
isLinux (missing) false
osMajorVersion 0 15
osVersionString 0.0.0 15.6.1
osFullNameForDisplay 0.0.0 macOS

Test plan

  • All 26 integration tests pass (15 frontier verbs + 11 system.environment)
  • Frontier.version() returns 11.0a6 (satisfies date.versionLessThan checks)
  • Frontier.cliVersion() returns full git tag string
  • system.environment.isMac = true, .isHeadless = true, .isPosix = true
  • Real OS version detected (15.6.1 macOS 24G90)
  • Unit tests: pre-existing migration segfault only (not caused by this PR)

🤖 Generated with Claude Code

…system

- Fix headless initenvironment() to detect actual platform via compile-time
  checks (#ifdef __APPLE__, __linux__, _WIN32) instead of setting all flags
  to false. On macOS, queries real OS version via sw_vers.

- Add three new system.environment flags:
  - isHeadless (true in CLI builds)
  - isPosix (true on macOS and Linux)
  - isLinux (true on Linux only)

- Unify version system: Frontier.version() now returns product version
  derived from git tags (CLI major + 10), e.g. v1.0.0-alpha.6 → "11.0a6".
  This preserves backward compat with date.versionLessThan() checks against
  legacy 7.x/10.x versions.

- Add Frontier.cliVersion() kernel verb returning the git-derived CLI
  distribution version string.

- Add tools/derive_product_version.sh for Makefile version derivation.

- Integration tests for all new environment flags and version verbs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c0623d034b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".


major=$(echo "$v" | sed -E 's/^([0-9]+).*/\1/')
rest=$(echo "$v" | sed -E 's/^[0-9]+\.//')
pmajor=$((major + 10))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Handle non-tag describe output in product version script

The derivation script assumes the input starts with digits, but frontier-cli/Makefile passes git describe --tags --always --dirty, and git describe -h documents that --always will "show abbreviated commit object as fallback" when no tag is available. In that case (for example shallow clones without tags), major becomes a hash like db0949d, pmajor=$((major + 10)) throws Illegal number, and FRONTIER_PRODUCT_VERSION_STRING ends up empty, so frontier.version() can return an empty string in non-tag builds.

Useful? React with 👍 / 👎.

Comment thread tools/derive_product_version.sh Outdated
esac
fi

if [ "$patch" = "0" ] || [ "$patch" = "$minor" ]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve patch number when minor equals patch

The condition if [ "$patch" = "0" ] || [ "$patch" = "$minor" ] incorrectly drops the patch component whenever minor and patch are numerically equal, so valid tags like v1.2.2 are converted to 11.2 instead of 11.2.2. This silently produces wrong product versions and can break ordering/compatibility checks that rely on full semantic version precision.

Useful? React with 👍 / 👎.

- derive_product_version.sh: Add input validation for bare commit hashes
  and non-tag git describe output (falls back to "11.0d" safely)
- derive_product_version.sh: Fix patch comparison — only omit patch when
  genuinely zero, not when minor == patch (v1.2.2 → 11.2.2 not 11.2)
- langstartup.c: Add isHeadless/isPosix/isLinux to non-headless
  initenvironment() so UserTalk scripts work portably across runtimes
- headless_frontier_verbs.c: Dedup version logic — frov_version case now
  calls frontierversion() instead of duplicating the #ifdef logic
- Add osBuildNumber integration test

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude

claude Bot commented Feb 15, 2026

Copy link
Copy Markdown

Code Review: PR #426 - Real Platform Detection + Unified Version System

I've reviewed this PR and have the following feedback:


Strengths

  1. Well-tested implementation: 26 integration tests (15 frontier verbs + 11 system.environment) with comprehensive coverage
  2. Good backward compatibility: Version mapping preserves compatibility with legacy date.versionLessThan() checks
  3. Clear documentation: PR description thoroughly explains the version mapping and system.environment changes
  4. Proper platform detection: Uses compile-time #ifdef macros correctly for cross-platform support
  5. Follows project conventions: Uses structured logging approach and proper test organization

🔍 Issues & Concerns

1. Memory Management - Potential Handle Leak (langstartup.c:299-323)

CRITICAL: The code creates handles but doesn't properly handle error cases. If unixshellcall() or any intermediate operation fails, execution may exit early without calling disposehandle(), causing a memory leak.

Recommendation:

  • Check return values from newtexthandle(), newemptyhandle(), and unixshellcall()
  • Use goto cleanup pattern or ensure disposal in all code paths
  • Reference: The full GUI version (lines 365-451) uses bundle blocks - consider similar structure

2. Error Handling - Silent Failures

The code doesn't check if unixshellcall() succeeds. If sw_vers fails (non-macOS system, sandboxing issue, missing binary), the code continues silently and could result in garbage data or empty strings in system.environment fields.

Recommendation:

  • Check unixshellcall() return value
  • Provide fallback values on failure (e.g., "unknown" for build number)
  • Consider adding debug logging for failures (per docs/LOGGING_STANDARDS.md)

3. Code Duplication

The handle allocation and sw_vers calling pattern is repeated twice (lines 299-306 and 311-318).

Recommendation: Extract to a helper function for better maintainability.

4. Shell Script - POSIX Compliance Issues (derive_product_version.sh)

The script uses sed -E which is not POSIX-compliant (GNU/BSD extension). May fail on minimal Unix systems or busybox environments.

Recommendation:

  • Use #!/bin/bash if bash features are required, OR
  • Use POSIX-compliant sed patterns

5. Shell Script - Edge Case Handling

The regex validation may have edge cases (e.g., v0.9.0 would give major=0, product version 10.0). The fallback "11.0d" may mask valid but unexpected version formats.

Recommendation:

  • Document expected input format more explicitly
  • Add test cases for edge inputs (comments in script)

🎯 Recommendations

Priority 1 (Must Fix)

  1. Fix memory management: Ensure handles are disposed on all code paths
  2. Add error handling: Check unixshellcall() return values and handle failures gracefully

Priority 2 (Should Fix)

  1. Shell script POSIX compliance: Use #!/bin/bash or make sed patterns POSIX-compliant
  2. Add logging: Use structured logging for diagnostics per docs/LOGGING_STANDARDS.md

Priority 3 (Nice to Have)

  1. Reduce duplication: Extract sw_vers helper function
  2. Document edge cases: Add comments for version derivation edge cases

📋 Testing Recommendations

The test coverage is excellent, but consider adding:

  1. Unit tests for derive_product_version.sh with various inputs
  2. Error path testing: What happens if sw_vers is missing or fails?
  3. Cross-platform validation: Run on Linux to ensure #ifdef linux path works

Architectural Compliance

Checked against project docs:

  • ✅ Follows docs/AI_SHARED_GUIDELINES.md: Integration tests in proper location
  • ✅ Follows docs/TESTING_GUIDE.md: Proper YAML test structure
  • ⚠️ docs/LOGGING_STANDARDS.md: Not using structured logging for diagnostics (consider adding)
  • ✅ No violations of docs/ARCHITECTURAL_ANTIPATTERNS.md

🎬 Verdict

Conditionally Approve pending fixes for:

  1. Memory leak potential (handle disposal)
  2. Missing error handling for unixshellcall()
  3. Shell script POSIX compliance

The core implementation is solid and well-tested. The issues identified are fixable and primarily concern robustness and error handling rather than fundamental design problems.

Great work on the comprehensive test coverage and clear documentation! 🚀

- langstartup.c: Add proper error handling for sw_vers handle allocation
  and unixshellcall() failures. Handles are always disposed on all paths.
  Falls back to "unknown" on failure instead of garbage/empty strings.
- langstartup.c: Add structured logging (LOG_COMP_STARTUP) for sw_vers
  results and failures per docs/LOGGING_STANDARDS.md.
- derive_product_version.sh: Change shebang to #!/bin/bash since sed -E
  is not POSIX sh compliant. Document edge cases and v0.x collision note.
  Use bash [[ ]] for input validation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude

claude Bot commented Feb 15, 2026

Copy link
Copy Markdown

Code Review: PR #426 - Real platform detection + unified version system

This PR introduces real platform detection for headless builds and unifies the version system. The implementation is generally solid with good test coverage. Below are my findings:


✅ Strengths

  1. Comprehensive test coverage: 26 integration tests (15 frontier verbs + 11 system.environment) provide excellent validation
  2. Cross-platform design: Proper use of #ifdef directives for macOS, Linux, and Windows detection
  3. Backward compatibility: Version mapping preserves compatibility with legacy date.versionLessThan() checks
  4. Clean separation: New frontier.cliVersion() verb cleanly separates CLI distribution version from product version
  5. Documentation: Clear inline comments and PR description with version mapping examples

🐛 Critical Issues

1. Memory Leak in Handle Management (langstartup.c:286-364)

Severity: HIGH - Memory leak on error paths

Location: Common/source/langstartup.c:286-364

Issue: The handle allocation pattern has multiple error paths that don't properly clean up both handles.

// Lines 286-298
Handle hcommand = nil, hreturn = nil;
boolean flgothandles;

flgothandles = newemptyhandle (&hreturn) && newtexthandle ("\psw_vers -buildVersion", &hcommand);

if (!flgothandles) {
    log_warn (LOG_COMP_STARTUP, "initenvironment: failed to allocate handles for sw_vers");
    
    if (hreturn != nil) disposehandle (hreturn);
    if (hcommand != nil) disposehandle (hcommand);
    // ... continues
}

Problem: If newemptyhandle(&hreturn) succeeds but newtexthandle(..., &hcommand) fails, the cleanup checks if (hcommand != nil) which may succeed even though hcommand was never initialized. This could lead to disposing an invalid handle or leaking hreturn.

Recommended Fix: Use explicit pattern from tests/headless_sys_verbs.c:133-146:

Handle hcommand = nil, hreturn = nil;

if (!newemptyhandle(&hreturn)) {
    log_warn(LOG_COMP_STARTUP, "initenvironment: failed to allocate hreturn");
    copyctopstring("unknown", bs);
    langassignstringvalue(ht, str_osBuildNumber, bs);
    langassignstringvalue(ht, str_osFullNameForDisplay, bs);
    goto cleanup_done;
}

if (!newtexthandle("\psw_vers -buildVersion", &hcommand)) {
    log_warn(LOG_COMP_STARTUP, "initenvironment: failed to allocate hcommand");
    disposehandle(hreturn);
    copyctopstring("unknown", bs);
    langassignstringvalue(ht, str_osBuildNumber, bs);
    langassignstringvalue(ht, str_osFullNameForDisplay, bs);
    goto cleanup_done;
}

// ... use handles ...

disposehandle(hcommand);
disposehandle(hreturn);

cleanup_done:
    // continue with rest of function

This ensures that only successfully allocated handles are disposed.


2. Shell Command Injection Risk (langstartup.c:318-326)

Severity: MEDIUM - Potential security issue

Location: Manual handle content manipulation for second shell command

sethandlesize (hreturn, 0);
copystring ("\psw_vers -productName", bs);
sethandlecontents (stringbaseaddress (bs), stringlength (bs), hcommand);

if (unixshellcall (hcommand, hreturn)) {

Issue: While safe in this specific case (hardcoded string), the pattern of manually manipulating handle contents for shell commands is error-prone and deviates from established patterns.

Recommendation: Use newtexthandle() or match the pattern from tests/headless_sys_verbs.c for consistency:

disposehandle(hcommand);
if (!newtexthandle("\psw_vers -productName", &hcommand)) {
    log_warn(LOG_COMP_STARTUP, "initenvironment: sw_vers -productName allocation failed");
    disposehandle(hreturn);
    copyctopstring("unknown", bsos);
    langassignstringvalue(ht, str_osFullNameForDisplay, bsos);
    goto cleanup_done;
}

⚠️ Minor Issues

3. Inconsistent Error Recovery Strategy

Lines 295-305 set "unknown" placeholders on allocation failure, but lines 310-317 and 328-336 continue to attempt operations even after unixshellcall() failures. Consider consolidating error paths.

4. Missing NULL Check After getsystemversionstring()

Line 271: getsystemversionstring(bsversion, NULL); - No validation that the function succeeded. If this can fail, add error handling.

5. Version Script Edge Case

tools/derive_product_version.sh:39 - When parsing patch version from rest2, if the string doesn't contain a second dot (e.g., "1.0"), patch will be empty. The comparison [ "$patch" = "0" ] should be [ "$patch" = "0" ] || [ -z "$patch" ] to handle malformed input.

Example failure case: Input "v1.0" (missing patch) would result in patch="", and line 58 would output "11.0.${stage}${sub}" with a trailing dot.

6. Logging Best Practices

Lines 312, 320, 330, 338 use log_warn() for shell command failures. Consider using log_debug() instead since fallback to "unknown" is graceful degradation, not a warning condition. This aligns with LOGGING_STANDARDS.md guidance.


📋 Style & Documentation

  1. Good: Platform detection using #ifdef is clean and follows C best practices
  2. Good: Test coverage includes platform-specific conditionals (sys.os() checks)
  3. Minor: Comment at line 213 could be more concise - the 3-line comment could be 1 line
  4. Good: ADR-level documentation in PR description (version mapping table, test plan)

🔍 Testing Concerns

  1. CI Status: Unable to verify CI checks passed (permission issue). Ensure all unit and integration tests pass.
  2. Cross-platform: Tests use sys.os() for conditional logic - verify behavior on Linux and Windows platforms, not just macOS
  3. Migration note: "pre-existing migration segfault" mentioned - ensure this is tracked in an issue

🎯 Recommendations

Before merge:

  1. Fix the handle management pattern to prevent memory leaks (Critical issue Repo Modernization: 64‑bit/ARM + DB Header Rev; Headless/Portable Runtime; Headless EFP Routing for file.* and Tests #1)
  2. Use consistent shell command handle creation (Medium issue Fix headless runtime warnings #2)
  3. Add edge case handling to version derivation script (Minor issue planning: reorganize phase structure and refresh docs #5)

Nice to have:
4. Consolidate error recovery paths for cleaner code
5. Adjust logging levels for graceful degradations
6. Verify cross-platform test execution on Linux/Windows


Summary

This is a well-designed feature with solid test coverage. The main concerns are around defensive programming in error paths (handle management) and edge case handling in the version derivation script. Once the critical handle management issue is addressed, this should be safe to merge.

The version unification strategy is elegant and maintains backward compatibility effectively. Good work on the comprehensive test coverage!

Recommendation: Request changes for critical issue #1, suggest fixes for issues #2 and #5 before merge.

- Rewrite sw_vers block with fully sequential allocation (no shared &&)
- Fresh newtexthandle for second command instead of sethandlecontents reuse
- goto swvers_fallback/swvers_done for consolidated error paths
- Use log_debug for graceful fallbacks (not log_warn)
- Guard empty $patch in version script (handles "v1.0" edge case)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude

claude Bot commented Feb 15, 2026

Copy link
Copy Markdown

PR Review: Real platform detection + unified version system

Overall Assessment

This is a well-executed PR that addresses important technical debt by replacing placeholder values with real platform detection. The implementation is clean, well-tested, and maintains backward compatibility. I have a few suggestions for improvement around error handling and code robustness.


Code Quality ✅

Strengths

  1. Excellent test coverage: 26 integration tests (12 new system.environment tests, 3 new frontier.version tests, updates to existing tests). All passing.

  2. Clear documentation: The PR description provides excellent context with version mapping examples and before/after comparisons.

  3. Backward compatibility preserved: The isCarbon flag maintained for legacy script compatibility is a smart touch.

  4. Good logging: Appropriate use of log_debug for sw_vers failures and fallback cases.

  5. Proper fallback handling: The code handles allocation failures and command failures gracefully with goto-based error handling.


Issues & Suggestions

🔴 Critical: Resource Leak in Error Path

File: Common/source/langstartup.c:313-315

if (!newtexthandle ("\psw_vers -buildVersion", &hcommand)) {
    log_debug (LOG_COMP_STARTUP, "initenvironment: hcommand alloc failed, using fallback");
    disposehandle (hreturn);  // ❌ hreturn disposed here
    goto swvers_fallback;
}

After this error, execution jumps to swvers_fallback which tries to assign to the hash table (safe), but then continues to swvers_done label. The problem is at line 339-345:

if (!newtexthandle ("\psw_vers -productName", &hcommand)) {
    log_debug (LOG_COMP_STARTUP, "initenvironment: hcommand alloc failed for productName");
    disposehandle (hreturn);  // ❌ DOUBLE DISPOSE - hreturn was already disposed above
    copyctopstring ("unknown", bsos);
    langassignstringvalue (ht, str_osFullNameForDisplay, bsos);
    goto swvers_done;
}

Issue: If the first newtexthandle fails, hreturn is disposed at line 314, but then at line 342 we try to dispose it again when the second newtexthandle fails.

Recommendation: Set hreturn = nil after disposing it, and check for NULL before disposing:

if (!newtexthandle ("\psw_vers -buildVersion", &hcommand)) {
    log_debug (LOG_COMP_STARTUP, "initenvironment: hcommand alloc failed, using fallback");
    if (hreturn) disposehandle (hreturn);
    hreturn = nil;
    goto swvers_fallback;
}

// Later...
if (!newtexthandle ("\psw_vers -productName", &hcommand)) {
    log_debug (LOG_COMP_STARTUP, "initenvironment: hcommand alloc failed for productName");
    if (hreturn) disposehandle (hreturn);
    hreturn = nil;
    // ...
}

🟡 Medium: Shell Script Portability

File: tools/derive_product_version.sh:6

# Uses sed -E (extended regex) which requires bash; not POSIX sh.

The script correctly documents that it requires bash, but the shebang #!/bin/bash assumes bash is at /bin/bash. On some systems (like NixOS), bash may be elsewhere.

Recommendation: Consider using #!/usr/bin/env bash for better portability, or verify this is acceptable for your build environment.

🟡 Medium: Version Parsing Robustness

File: Common/source/langstartup.c:275-293

The version parsing uses nthfield() and stringtonumber() without validating the results. If getsystemversionstring() returns an unexpected format, this could result in uninitialized values.

Recommendation: Add validation:

if (stringlength(bsmajor) > 0) {
    stringtonumber (bsmajor, &x);
    langassignlongvalue (ht, str_osMajorVersion, x);
} else {
    langassignlongvalue (ht, str_osMajorVersion, 0);
}

🟡 Medium: Missing Error Check

File: Common/source/langstartup.c:348

sethandlesize (hreturn, 0);

The return value of sethandlesize() is not checked. If this fails, the subsequent unixshellcall() may behave unexpectedly.

Recommendation: Check return value or add a comment explaining why failure is acceptable here.


Best Practices ✅

  1. Good use of conditional compilation: Platform detection with #ifdef __APPLE__, __linux__, _WIN32 is clean and standard.

  2. Proper bigstring usage: Pascal strings handled correctly throughout.

  3. Clear control flow: The goto-based error handling pattern (swvers_fallback, swvers_done) is appropriate for C and matches the codebase style.


Test Coverage ✅

The test coverage is excellent:

  • ✅ Platform flags tested cross-platform (using sys.os() for portability)
  • ✅ Version string validation (checks for non-zero values)
  • ✅ Backward compatibility verified (date.versionLessThan() checks)
  • ✅ New frontier.cliVersion() verb tested
  • ✅ Edge cases handled in shell script (bare commit hashes, empty input)

Minor suggestion: Consider adding a unit test for derive_product_version.sh with the documented edge cases:

./tools/derive_product_version.sh "v1.0.0-alpha.6"  # Should output: 11.0a6
./tools/derive_product_version.sh "db0949d"         # Should output: 11.0d
./tools/derive_product_version.sh ""                # Should output: 11.0d

Performance Considerations ✅

The sw_vers calls happen only at startup during initenvironment(), so the performance impact is negligible. The shell command overhead is acceptable for one-time initialization.


Security Concerns ✅

  1. Command execution: The use of unixshellcall() with hardcoded commands (sw_vers -buildVersion, sw_vers -productName) is safe - no user input is involved.

  2. Buffer handling: Pascal strings have fixed length limits, preventing buffer overflows.

  3. No injection risks: All commands are hardcoded literals.


Documentation ✅

The PR description is excellent:

  • Clear before/after tables
  • Version mapping examples
  • Complete test plan with checkmarks

Suggestion: Consider adding a note to docs/TESTING_GUIDE.md or similar about the new version system for future maintainers.


Summary

This is a high-quality PR that properly addresses platform detection. The main issues are:

  1. Critical: Potential double-dispose of hreturn in error paths (easy fix)
  2. Medium: Add validation for version string parsing
  3. Medium: Check sethandlesize() return value or document why it's safe to ignore

After addressing the double-dispose issue, this PR should be safe to merge. The backward compatibility handling and test coverage are exemplary.

Recommendation: ✅ Approve after fixing the double-dispose issue


Additional Questions

  1. Have you tested this on Linux to verify the platform detection works correctly there?
  2. What happens if getsystemversionstring() returns an empty string or unexpected format?
  3. Is there a reason the full application path (non-FRONTIER_HEADLESS) also sets the new flags (isHeadless, isPosix, isLinux) at lines 208-220? Should these be in a shared header to avoid duplication?

…ity (review round 4)

- Nil out hreturn after dispose to prevent potential double-dispose
- Validate nthfield() results before stringtonumber() (empty string guard)
- Document sethandlesize(0) safety (shrinking to zero never fails)
- Use #!/usr/bin/env bash for portability across systems

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude

claude Bot commented Feb 15, 2026

Copy link
Copy Markdown

Code Review - PR #426: Real platform detection + unified version system

Overall Assessment

This is a solid enhancement that addresses real deficiencies in the headless mode's environment detection. The implementation is well-structured, thoroughly tested (26 integration tests covering the new functionality), and includes good backward compatibility considerations. However, there are a few resource management concerns and minor improvement opportunities.

Critical Issues

1. Resource Leak in Error Path 🔴

Location: Common/source/langstartup.c:320-326

When newtexthandle() fails for the build number command, you dispose of hreturn but there's a potential leak scenario:

if (!newtexthandle ("\psw_vers -buildVersion", &hcommand)) {
    log_debug (LOG_COMP_STARTUP, "initenvironment: hcommand alloc failed, using fallback");
    disposehandle (hreturn);
    hreturn = nil;
    goto swvers_fallback;
}

If unixshellcall() fails after this point (line 328), you jump to cleanup at line 344-345 which tries to dispose hcommand and hreturn. However, if the second newtexthandle() (line 349) fails, you dispose hreturn again (line 352) before going to swvers_done, which could be a double-free if hreturn wasn't re-allocated.

Recommendation:

  • Set hcommand = nil and hreturn = nil after each disposal
  • Consider restructuring to have a single cleanup path

2. Missing Error Recovery for sethandlesize() Comment ⚠️

Location: Common/source/langstartup.c:358

The comment says "safe to ignore: shrinking to zero never fails" but this is an assumption about the implementation. While typically true, defensive programming would check the return value or document why this specific case is guaranteed safe.

Recommendation: Add a reference to the implementation documentation, or assert the result in debug builds.

Code Quality Issues

3. Shell Script Portability ⚠️

Location: tools/derive_product_version.sh

The script uses sed -E (extended regex) and bash-specific regex matching (=~), which is correctly documented as requiring bash. However, the shebang is #!/usr/bin/env bash, which is good.

Minor concern: Multiple echo | sed pipelines could be more efficient. Consider:

# Current approach (multiple sed invocations):
major=$(echo "$v" | sed -E 's/^([0-9]+).*/\1/')
rest=$(echo "$v" | sed -E 's/^[0-9]+\.//')
pmajor=$((major + 10))
minor=$(echo "$rest" | sed -E 's/^([0-9]+).*/\1/')

# More efficient (single read with IFS):
IFS='.-' read -r major minor patch stage_rest <<< "$v"
pmajor=$((major + 10))

However, the current approach is clearer and this is not performance-critical. The readability trade-off is acceptable.

4. Test Script Syntax Issue 🟡

Location: tests/integration/test_cases/system_environment.yaml

Lines 21, 33, 45, 70, 77, 84, etc. have closing braces in the wrong position:

script: |
  if sys.os() == "MacOS" {
    return system.environment.isMac}  # ← Brace should be on next line

While UserTalk may tolerate this, it violates typical formatting conventions and reduces readability.

Recommendation: Fix formatting:

  if sys.os() == "MacOS" {
    return system.environment.isMac
  }

Design & Architecture

5. Platform Detection Duplication 📋

The headless initenvironment() now has platform-specific #ifdef blocks (lines 230-254) that duplicate logic also present in the non-headless path (lines 218-230 in the original diff context). There's also duplication of the new flags in the non-headless path (lines 218-230 in the later section).

Concern: If platform detection logic changes, it must be updated in multiple places.

Recommendation: Consider extracting platform detection to a shared helper function or macro, though this may conflict with the existing architecture. Document the duplication rationale if intentional.

6. Version Mapping Complexity 📋

The product version derivation (CLI major + 10) is clever but adds cognitive overhead. The mapping v1.0.0-alpha.6 → 11.0a6 is non-obvious.

Strengths:

  • Maintains backward compatibility with date.versionLessThan() checks
  • Well-documented in code comments and PR description
  • Comprehensive edge case handling

Recommendations:

  • Add this mapping to project documentation (consider docs/VERSION_SCHEME.md)
  • Document the rationale for choosing major+10 (vs. major+1000 or other schemes)

Testing

7. Excellent Test Coverage

The 26 integration tests (15 frontier verbs + 11 system.environment) are comprehensive and cover:

  • Platform detection flags
  • Version string formatting
  • Cross-platform compatibility
  • Legacy compatibility checks

Particularly good:

  • Tests validate against sys.os() for platform-agnostic verification
  • Version comparison tests ensure backward compatibility
  • Graceful degradation on non-macOS platforms

8. Test Cleanup 📋

Several file dialog tests were removed (lines 322-575 in diff), reducing coverage from 26→14 tests in that suite. The PR description doesn't explain why.

Recommendation: If these tests were moved or deprecated, mention in the commit message or PR description.

Security Considerations

9. Shell Command Execution 🔒

Location: Common/source/langstartup.c:328, 360

The code executes sw_vers -buildVersion and sw_vers -productName via unixshellcall().

Security assessment:

  • ✅ Commands are hardcoded (no user input)
  • ✅ macOS-only, using trusted system utility
  • ✅ Graceful fallback on failure

Low risk, but worth noting for security audits.

Performance

10. Startup Cost ⏱️

The macOS path now makes two shell callouts (sw_vers twice) during initialization. This adds ~10-50ms to startup time.

Assessment: Acceptable trade-off for accurate OS detection. The non-macOS path is fast (no external calls).

Recommendation: If startup time becomes critical, consider caching or lazy evaluation.

Documentation

11. Strong Documentation

  • Inline comments explain platform detection strategy
  • Version derivation script has excellent examples (lines 8-20)
  • Edge case handling is documented (lines 17-20)
  • PR description includes version mapping table

Suggestion: Add a one-line comment explaining why CLI major + 10 was chosen (e.g., "Offset by 10 to exceed legacy Frontier 7.x and 10.x versions").

Best Practices

12. Logging Compliance

Uses log_debug() with LOG_COMP_STARTUP consistently, following the project's logging standards.

13. Backward Compatibility

  • Preserves isCarbon flag for legacy scripts (line 234, 240)
  • Product version satisfies date.versionLessThan() checks
  • New flags (isHeadless, isPosix, isLinux) are additive

Minor Improvements

14. Magic Number 📋

Location: tools/derive_product_version.sh:36

pmajor=$((major + 10))

Consider defining a named constant or adding an inline comment explaining the offset.

15. BIGSTRING Macro Inconsistency 📋

Location: tests/headless_frontier_verbs.c:948

The forward declaration comment says "defined below, also called directly by langhtml.c" but doesn't explain why it's forward-declared here. Minor documentation improvement opportunity.

Summary

Category Count
🔴 Critical Issues 1
⚠️ Warnings 2
🟡 Minor Issues 1
📋 Suggestions 6
✅ Strengths 5

Recommendation: Request changes to address the resource leak concern (#1). The test formatting (#4) should also be fixed for consistency. Other items are suggestions for improvement but not blockers.

Strengths: Well-tested, thoughtfully designed, good backward compatibility, strong documentation.


Generated by code review bot • Following Frontier development guidelines

@jsavin jsavin merged commit ab18bf9 into develop Feb 15, 2026
1 check passed
@jsavin

jsavin commented Feb 15, 2026

Copy link
Copy Markdown
Owner Author

Merge Rationale

Merged after 4 rounds of review feedback, all addressed:

Round 1 (Codex): Fixed bare commit hash crash in version script + patch==minor comparison bug.

Round 2 (Claude + local bar-raiser): Added isHeadless/isPosix/isLinux to non-headless path, deduped frontierversion() logic, added error checking on handle allocation/unixshellcall, added osBuildNumber test.

Round 3 (Claude): Rewrote sw_vers block with fully sequential handle allocation (no shared &&), fresh newtexthandle for second command instead of sethandlecontents reuse, goto-based cleanup pattern, log_debug for graceful fallbacks.

Round 4 (Claude): Nil out hreturn after dispose to prevent potential double-dispose, validated nthfield() results before stringtonumber(), documented sethandlesize(0) safety, changed shebang to #!/usr/bin/env bash.

Remaining review suggestions not addressed (non-blocking):

  • Test formatting (closing braces): UserTalk requires } on the same line as the preceding statement in certain contexts -- this is a documented language constraint, not a style issue.
  • Platform detection duplication: The headless and non-headless initenvironment() paths are intentionally separate codebases with different compilation contexts. Extracting shared helpers would add complexity without clear benefit.
  • Magic number comment on major + 10: Already documented in the script header (lines 3, 22-23) and PR description.
  • sed pipeline efficiency: Reviewer acknowledged the readability trade-off is acceptable for a non-performance-critical build-time script.

All 27 integration tests passing (15 frontier_verbs + 12 system_environment). CI green.

@jsavin jsavin deleted the feature/env-version branch February 15, 2026 09:23
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