Skip to content

chore: drop legacy visual studio project files#10

Merged
jsavin merged 1 commit into
developfrom
chore/remove-legacy-vc-projects
Oct 13, 2025
Merged

chore: drop legacy visual studio project files#10
jsavin merged 1 commit into
developfrom
chore/remove-legacy-vc-projects

Conversation

@jsavin

@jsavin jsavin commented Oct 13, 2025

Copy link
Copy Markdown
Owner

Summary

  • remove the unmaintained Visual Studio 6/2003/2005/2008 project directories
  • update docs and planning notes to reflect the removal and mark Windows builds as legacy
  • simplify the MySQL client docs now that Windows projects are gone

Testing

  • not run (project removal/doc updates only)

@jsavin jsavin merged commit c9c643d into develop Oct 13, 2025
1 check passed
@jsavin jsavin deleted the chore/remove-legacy-vc-projects branch October 13, 2025 17:52
jsavin added a commit that referenced this pull request Feb 10, 2026
- #1: Enable system.compiler.threads registration (was TODO/deferred).
  Register before globals swap, unregister after restore. evaluate uses
  "anonymous", callscript uses script verb name.
- #2: Save/restore langerrordisable, tryerror, tryerrorstack in thread
  globals swap (matching legacy copythreadglobals from process.c).
- #3: Document cooperative kill() limitation (no yield points yet).
- #4: Error state audit confirmed isolation is complete for all globals
  saved by legacy Frontier. Added 3 missing struct-field globals.
- #5: Check pthread_cond_timedwait return value, log errors.
- #7: Add upper bounds check in get_nth_thread_id (n > MAX_THREADS).
- #8: Replace magic number 2 with idapplicationthread constant.
- #9: Document return semantics for evaluate and callscript.
- #10: Normalize test timeouts to 3s.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
jsavin added a commit that referenced this pull request Feb 10, 2026
#404)

* feat: Add cooperative threading with thread registry for headless mode

Implement cooperative threading infrastructure matching legacy Frontier's
fire-and-forget thread model. Threads run synchronously (one at a time)
with proper globals save/restore to isolate thread state.

Key changes:
- Thread registry: register_main_thread(), get_nth_thread_id() for
  singleton thread ID allocation. Main thread gets ID 2 (idapplicationthread),
  spawned threads start at 3+.
- Thread globals: alloc/dispose/save/restore functions that properly handle
  C globals (fllangerror, flreturn, flbreak, etc.) separate from the
  hthreadglobals struct pointer swap.
- Thread verbs: Rewrite all thread.* verb implementations to use registry
  and cooperative globals swap (evaluate, callscript, getCurrentID, getCount,
  exists, kill, sleep, wake, getNthID).
- Error containment: scriptError() in spawned thread stops execution within
  that thread but does not propagate to the calling thread.
- Build: Link threadregistry.c into CLI binary, initialize at startup.
- Tests: 10 integration tests (all passing), expanded registry unit tests.

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

* fix: Address Codex review feedback on cooperative threading

P1: Propagate callscript launch failures to the caller. When langrunscript
fails (bad script name, parameter binding, etc.), thread.callscript now
returns false instead of silently reporting success with a thread ID.

P2: Initialize spawned thread cwd from process default. Matches legacy
newthreadglobals (process.c:1426) so that relative file operations in
thread.evaluate/thread.callscript see the correct working directory.

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

* fix: Address Claude review feedback — callscript resolution split and tests

#1: Add NULL check for register_main_thread() in main.c. Startup now
fails cleanly instead of silently continuing without a registered main thread.

#3: Use memset to reset thread record slots on mutex/condvar init failure
in register_main_thread(), ensuring pristine state for slot reuse.

#4/#5: Split thread.callscript into resolution and execution phases.
Script name resolution, lookup, and compilation happen in the MAIN thread
context (failures propagate to caller). Execution via langrunscriptcode
happens in the cooperative thread context (runtime errors are fire-and-forget).
This correctly distinguishes spawn failures from runtime errors.

Add 4 thread.callscript integration tests:
- Basic execution with ODB side effects
- Parameter passing (on myScript(x) pattern)
- Error containment (scriptError is fire-and-forget)
- Nonexistent script (resolution failure propagates to caller)

14/14 thread integration tests passing.

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

* fix: Address Claude bot review feedback on cooperative threading

- #1: Enable system.compiler.threads registration (was TODO/deferred).
  Register before globals swap, unregister after restore. evaluate uses
  "anonymous", callscript uses script verb name.
- #2: Save/restore langerrordisable, tryerror, tryerrorstack in thread
  globals swap (matching legacy copythreadglobals from process.c).
- #3: Document cooperative kill() limitation (no yield points yet).
- #4: Error state audit confirmed isolation is complete for all globals
  saved by legacy Frontier. Added 3 missing struct-field globals.
- #5: Check pthread_cond_timedwait return value, log errors.
- #7: Add upper bounds check in get_nth_thread_id (n > MAX_THREADS).
- #8: Replace magic number 2 with idapplicationthread constant.
- #9: Document return semantics for evaluate and callscript.
- #10: Normalize test timeouts to 3s.

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

* fix: Defensive cleanup, shutdown docs, and consistent error logging

- Add langdisposetree() guard in thread evaluate error path
- Document single-threaded shutdown assumption in main.c cleanup
- Replace remaining magic number 2 with idapplicationthread in cleanup
- Add log_error to all silent failure paths in allocate_thread_record

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
jsavin added a commit that referenced this pull request Mar 20, 2026
…n tests

Add two new test files covering integration test gaps #9 and #10:

- webserver_http_roundtrip_tests.yaml (9 tests, 7 active, 2 skipped):
  Tests HTTP request/response round-trip at the TCP transport layer using
  tcp.listenStream callbacks. Covers GET, POST, Content-Type headers, path
  extraction, sequential requests, 404 responses, and large response bodies.
  Full inetd/webserver stack tests are skipped pending fwsNetEvent* migration.

- bigstring_boundary_tests.yaml (27 tests):
  Documents behavior at the 255-byte bigstring boundary (lenbigstring limit).
  Tests string creation, concatenation, content integrity, ODB storage,
  comparison, sizeOf/string.length agreement, file paths, substring
  operations, pattern matching, and environment variables at 254/255/256 bytes.
  Confirms UserTalk heap strings are NOT subject to the 255 limit.

Key findings documented in test comments:
- tcp.readStream() returns binary data type for empty reads; sizeOf() on
  empty binary returns -4, requiring thread.sleepFor() between write and poll
- UserTalk string variables are heap-allocated with no 255-byte limit
- The bigstring limit only affects C-level APIs (file paths, env vars)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jsavin added a commit that referenced this pull request Mar 21, 2026
* test: Add webserver HTTP round-trip and bigstring boundary integration tests

Add two new test files covering integration test gaps #9 and #10:

- webserver_http_roundtrip_tests.yaml (9 tests, 7 active, 2 skipped):
  Tests HTTP request/response round-trip at the TCP transport layer using
  tcp.listenStream callbacks. Covers GET, POST, Content-Type headers, path
  extraction, sequential requests, 404 responses, and large response bodies.
  Full inetd/webserver stack tests are skipped pending fwsNetEvent* migration.

- bigstring_boundary_tests.yaml (27 tests):
  Documents behavior at the 255-byte bigstring boundary (lenbigstring limit).
  Tests string creation, concatenation, content integrity, ODB storage,
  comparison, sizeOf/string.length agreement, file paths, substring
  operations, pattern matching, and environment variables at 254/255/256 bytes.
  Confirms UserTalk heap strings are NOT subject to the 255 limit.

Key findings documented in test comments:
- tcp.readStream() returns binary data type for empty reads; sizeOf() on
  empty binary returns -4, requiring thread.sleepFor() between write and poll
- UserTalk string variables are heap-allocated with no 255-byte limit
- The bigstring limit only affects C-level APIs (file paths, env vars)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: Update OPML exports for new integration test files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: Address PR #485 review feedback

- Fix ODB content integrity test: 246→248 fill bytes for correct 256-byte total
- Move HTTP test ports from 11000 range to ephemeral 49200+ range
- Add try/else error-path cleanup to all active HTTP tests so
  tcp.closeListen runs even if client operations fail
- Add body content assertion to large response test (size + content check)
- Regenerate OPML reports

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: Tighten large response body assertion in webserver tests

Extract body after \r\n\r\n header separator and verify body length >= 500,
rather than checking total response size which trivially passes due to
~60 bytes of HTTP headers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: Document bigstring C-level truncation limitations and add 256-byte env var test

Add comment to file path tests (category 7) explaining that they only
test UserTalk string construction, not C-level bigstring truncation
(tracked under issue #475).

Add env var test at 256 bytes that confirms truncation occurs: the
value is truncated from 256 to 255 bytes when round-tripping through
sys.setenvironmentvariable/sys.getenvironmentvariable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: Use distinct ports per test and clean up env vars

Add port assignment documentation comment block to webserver tests
(ports were already unique 49200-49206, but now documented).

Add env var cleanup in bigstring boundary tests - both the 255-byte
and 256-byte env var tests now reset their variables to empty string
before returning to prevent leakage between test runs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jsavin added a commit that referenced this pull request Mar 21, 2026
Resolve conflicts:
- INTEGRATION_TEST_GAPS.md: keep Done status for gaps #6-#10 from both sides
- OPML files: accept develop's versions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jsavin added a commit that referenced this pull request Jun 30, 2026
Round 2 of M1: fold in the three P1 findings from the local /gate review
(security + concurrency reviewers) plus the cheap P2s that are part of
the same edits.  No behavior change to the existing 12 M1 tests; one new
test exercises the back-pressure surface.

Concurrency P1 -- input_decoder.h threading contract was wrong:
- Previous text said "single-threaded, GIL-held" then "releases the GIL
  before entering the read loop", which contradict each other and would
  have misled the M6 sub-agent.
- Rewrite the threading block to state the single-owner invariant
  explicitly: exactly one decoder per process, GIL held at every API
  entry/exit, GIL dropped ONLY inside the M6 blocking read inside
  input_decoder_poll, mutations during that window are safe because no
  other thread holds a pointer to the decoder.

Concurrency P1 -- set_mouse / kitty_enable owner-thread invariant was
implicit:
- Document that these must be called from GIL-held context AND only when
  no poll is in progress.  The REPL event loop satisfies this naturally
  (slash commands dispatch between polls), but it needs to be a
  documented invariant rather than an accident, because M3+ will turn
  these into TTY writes that would race the in-flight read(2) otherwise.

Security P1 -- silent drop-on-overflow contract:
- Previous inject_bytes returned void and silently truncated.  M2/M3
  read-loop overflow would have been an invisible parser-desync surface.
- Change inject_bytes to return the number of bytes accepted (size_t).
- Add a monotonic dropped_bytes counter on the struct, exposed via
  input_decoder_dropped_bytes() (test seam, mirrors buffered_bytes).
- Add behavioral test test_inject_overflow_increments_dropped_counter
  that floods 5 KiB into the 4 KiB ring and asserts accepted+dropped =
  attempted, then verifies a second inject when full drops everything.

Cheap P2s folded in:
- Rename head_len -> fill_len (bar-raiser P2 #6: "head" implied an index,
  it's actually a fill level).  Will keep the M2 state-machine commit
  honest about what's an index vs a count.
- assert(fill_len <= INPUT_DECODER_BUFFER_SIZE) at top of inject_bytes
  (bar-raiser P2 #4): cheap insurance for the M2 drain refactor.
- assert(bytes != NULL) when len > 0 (security P2): test seam should
  catch caller bugs, not silently no-op.
- Add input_decoder_kitty_enabled() symmetric query (bar-raiser P2 #7):
  the field was write-only with no observer; tests can now assert the
  bit flipped, and M5 has the seam pre-built.
- Document tty_fd ownership: caller owns the fd, decoder does not
  validate or close it (bar-raiser P2 #5/8).
- Document SIGWINCH non-interaction (concurrency P2 #12).
- Unify the threading comment between header and .c (concurrency P2 #11).

Test-harness P2 (bar-raiser #5):
- Rename all 49 SKIP-stub functions test_* -> test_skip_* so a grep over
  tests/tmp/unit/input_decoder_tests.json discloses the deferred set
  without parsing stderr.
- Add g_skip_count counter bumped by tr_skip(); main() prints
  "[skip-summary] 49 of 62 tests are SKIP stubs deferred to M2-M5"
  alongside the green tally so the 62/62 doesn't conceal unimplemented
  behavior.

Test count:
  Before: 61/61 (12 real + 49 SKIP).
  After:  62/62 (13 real + 49 SKIP).
  Net suite: 882 -> 883 (no other tests touched).

Deferred to follow-up issues (P2s not folded in here):
- Forward-compat note about future M2 signed/unsigned hazard in drain
  arithmetic (security P2 #10) -- belongs in the M2 PR review checklist.
- "Document the implementation's actual behavior of bytes==NULL" --
  resolved by switching to assert (no separate doc needed now).

Plan: planning/phase_c/INPUT_DECODER_PLAN.md
PR: #816
jsavin added a commit that referenced this pull request Jun 30, 2026
* feat(boxen): C M1 #809 -- input_decoder PTY-replay harness + stub

Phase C input-decoder milestone M1.  Pure infrastructure: a stub decoder
module and a 61-test harness that exercises the M1 API surface (create /
destroy / inject-bytes / poll / mouse-enable / kitty-enable).

What this adds:
- frontier-cli/boxen/input_decoder.h -- private API (typedef, lifecycle,
  poll, mouse / kitty enable, INPUT_DECODER_TEST_SEAM-guarded inject /
  buffered-bytes accessor).
- frontier-cli/boxen/input_decoder.c -- minimal skeleton: 4 KiB linear
  scratch buffer, NULL-safe everywhere.  poll() always returns
  BOXEN_ERR_TIMEOUT (the state machine lands in M2).  Wired into the
  frontier-cli production build so the CLI continues to link, but NOT yet
  wired into backend_tb2.c (the M6 cutover).
- tests/input_decoder_tests.c -- TR_RUN harness.  12 M1 behavioral tests
  (create / destroy round-trip, NULL safety, mouse-enable round-trip,
  inject deposits bytes, poll-on-empty returns TIMEOUT, etc.).  49 SKIP
  stubs ranged by milestone (M2: cursor keys + UTF-8, M3: mouse, M4:
  paste, M5: Kitty).  Each SKIP stub prints "[SKIP] <protocol entry>" to
  stderr so deferrals are visible in the test log; the M2-M5 sub-agents
  rewrite each stub as a behavioral assert when its milestone lands.
- tests/Makefile -- new input_decoder_tests target (link slice:
  input_decoder.c only, no termbox2, no Frontier runtime; uses
  -DINPUT_DECODER_TEST_SEAM to expose the inject seam).
- frontier-cli/Makefile -- input_decoder.c added to BOXEN_SOURCES.

SKIP mechanism note (no TR_SKIP exists in test_report.h): the SKIP stubs
return without firing assert(), so TR_RUN records them as passing.  This
keeps the 61/61 green count accurate (we are not claiming protocol
behavior we have not implemented).  The early-return + stderr SKIP line
makes the deferral visible in the log without polluting the JSON tally.

Done criterion (per plan section 7, M1):
  make -C tests input_decoder_tests && ./tests/input_decoder_tests
  --> compiles, passes (61/61 green, of which 49 print SKIP).
  Full unit suite: 882/882 (was 821 pre-existing, +61 new).

Out of scope for M1 (per plan section 7): the state machine (M2), SGR
mouse (M3), bracketed paste with BOXEN_EV_PASTE ABI add (M4), Kitty
keyboard protocol (M5), backend_tb2 cutover (M6), /mouse toggle (M7).
No production input-path behavior changes; backend_tb2.c is untouched.

Plan: planning/phase_c/INPUT_DECODER_PLAN.md
Closes #809

* fix(boxen): C M1 #809 -- address /gate P1 findings (3) + cheap P2s

Round 2 of M1: fold in the three P1 findings from the local /gate review
(security + concurrency reviewers) plus the cheap P2s that are part of
the same edits.  No behavior change to the existing 12 M1 tests; one new
test exercises the back-pressure surface.

Concurrency P1 -- input_decoder.h threading contract was wrong:
- Previous text said "single-threaded, GIL-held" then "releases the GIL
  before entering the read loop", which contradict each other and would
  have misled the M6 sub-agent.
- Rewrite the threading block to state the single-owner invariant
  explicitly: exactly one decoder per process, GIL held at every API
  entry/exit, GIL dropped ONLY inside the M6 blocking read inside
  input_decoder_poll, mutations during that window are safe because no
  other thread holds a pointer to the decoder.

Concurrency P1 -- set_mouse / kitty_enable owner-thread invariant was
implicit:
- Document that these must be called from GIL-held context AND only when
  no poll is in progress.  The REPL event loop satisfies this naturally
  (slash commands dispatch between polls), but it needs to be a
  documented invariant rather than an accident, because M3+ will turn
  these into TTY writes that would race the in-flight read(2) otherwise.

Security P1 -- silent drop-on-overflow contract:
- Previous inject_bytes returned void and silently truncated.  M2/M3
  read-loop overflow would have been an invisible parser-desync surface.
- Change inject_bytes to return the number of bytes accepted (size_t).
- Add a monotonic dropped_bytes counter on the struct, exposed via
  input_decoder_dropped_bytes() (test seam, mirrors buffered_bytes).
- Add behavioral test test_inject_overflow_increments_dropped_counter
  that floods 5 KiB into the 4 KiB ring and asserts accepted+dropped =
  attempted, then verifies a second inject when full drops everything.

Cheap P2s folded in:
- Rename head_len -> fill_len (bar-raiser P2 #6: "head" implied an index,
  it's actually a fill level).  Will keep the M2 state-machine commit
  honest about what's an index vs a count.
- assert(fill_len <= INPUT_DECODER_BUFFER_SIZE) at top of inject_bytes
  (bar-raiser P2 #4): cheap insurance for the M2 drain refactor.
- assert(bytes != NULL) when len > 0 (security P2): test seam should
  catch caller bugs, not silently no-op.
- Add input_decoder_kitty_enabled() symmetric query (bar-raiser P2 #7):
  the field was write-only with no observer; tests can now assert the
  bit flipped, and M5 has the seam pre-built.
- Document tty_fd ownership: caller owns the fd, decoder does not
  validate or close it (bar-raiser P2 #5/8).
- Document SIGWINCH non-interaction (concurrency P2 #12).
- Unify the threading comment between header and .c (concurrency P2 #11).

Test-harness P2 (bar-raiser #5):
- Rename all 49 SKIP-stub functions test_* -> test_skip_* so a grep over
  tests/tmp/unit/input_decoder_tests.json discloses the deferred set
  without parsing stderr.
- Add g_skip_count counter bumped by tr_skip(); main() prints
  "[skip-summary] 49 of 62 tests are SKIP stubs deferred to M2-M5"
  alongside the green tally so the 62/62 doesn't conceal unimplemented
  behavior.

Test count:
  Before: 61/61 (12 real + 49 SKIP).
  After:  62/62 (13 real + 49 SKIP).
  Net suite: 882 -> 883 (no other tests touched).

Deferred to follow-up issues (P2s not folded in here):
- Forward-compat note about future M2 signed/unsigned hazard in drain
  arithmetic (security P2 #10) -- belongs in the M2 PR review checklist.
- "Document the implementation's actual behavior of bytes==NULL" --
  resolved by switching to assert (no separate doc needed now).

Plan: planning/phase_c/INPUT_DECODER_PLAN.md
PR: #816
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