Skip to content

lexer#2

Merged
MarkEdmondson1234 merged 1 commit into
mainfrom
dev
Sep 26, 2025
Merged

lexer#2
MarkEdmondson1234 merged 1 commit into
mainfrom
dev

Conversation

@MarkEdmondson1234

Copy link
Copy Markdown
Member

No description provided.

@sunholo-voight-kampff

Copy link
Copy Markdown
Collaborator

🤖 Agent Working

I've picked up this issue and am working on it.

Field Value
Task ID task-d4d3e972
Agent AILANG Coordinator
Stage Design Document
Status In Progress

You'll receive updates as I make progress.

@sunholo-voight-kampff

Copy link
Copy Markdown
Collaborator

📋 Design Document Ready

I've created a design document for this issue.

Summary

Field Value
Task ID task-d4d3e972
Duration 5m3.856603583s
Cost $0.7830
Tokens 14050 (127 in / 13923 out)

📄 Design Document: design_docs/planned/PUMPKIN_HARVESTING_FIX.md (click to expand)

Pumpkin Harvesting Fix - Design Document

Summary

The pumpkin crop is not harvestable despite being properly configured in the farming system. Investigation revealed the root cause: pumpkin crop sprite assets are missing from the assets definition file. While tomato has both plant_tomato_young and plant_tomato_adult sprites defined, pumpkin has no corresponding plant_pumpkin_young and plant_pumpkin_adult sprites defined in assets.ts. This causes the TileLayer to fail silently when trying to render pumpkin crops, preventing them from transitioning to the visible SOIL_READY state needed for harvesting.

Problem Analysis

What Works

  • Crop Definition: Pumpkin is fully defined in data/crops.ts with proper growth times, water requirements, and yields
  • Seed System: Pumpkin seeds (seed_pumpkin) are properly defined and can be planted
  • Farm Manager: The farming system correctly tracks pumpkin plots through growth states
  • Harvesting Logic: The action handler has full support for harvesting SOIL_READY crops
  • Visual Config: TileLayer has proper size configuration for pumpkin crops at line 67

What's Missing

The assets definition in assets.ts is missing:

  • plant_pumpkin_young - Young pumpkin growth stage sprite
  • plant_pumpkin_adult - Mature pumpkin harvest-ready sprite

Why This Breaks Harvesting

  1. Player plants pumpkin seeds on a farm plot
  2. FarmManager correctly tracks the plot as it grows through PLANTED → WATERED → READY states
  3. When TileLayer tries to render the crop visually, it looks up farmingAssets.plant_pumpkin_young and farmingAssets.plant_pumpkin_adult
  4. These assets are undefined, so the rendering fails silently
  5. The player sees no visual feedback that the crop is growing
  6. Even when the crop reaches SOIL_READY state, the player cannot see it to interact with it
  7. The interaction system requires a visible plot tile to offer the "Harvest Crop" option (via getAvailableInteractions)

Console Evidence

User reported: "When looking in the console, I don't see either the word harvest or plot" - indicating the crop is either not being tracked as SOIL_READY or the rendering is failing silently without error messages.

Design

Asset Architecture

The farming assets follow a consistent pattern for crop sprites:

// Each harvestable crop has two growth stage sprites:
plant_[cropname]_young: '/TwilightGame/assets-optimized/farming/[cropname]_young.png',
plant_[cropname]_adult: '/TwilightGame/assets-optimized/farming/[cropname]_adult.png',

Crop Sprites Already Defined (for reference):

  • plant_tomato_young and plant_tomato_adult
  • plant_corn_young and plant_corn_adult
  • plant_radish_young and plant_radish_adult
  • plant_spinach_young and plant_spinach_adult
  • plant_carrot_young and plant_carrot_adult
  • plant_cucumber_young and plant_cucumber_adult
  • plant_onion_young and plant_onion_adult
  • plant_sunflower_young and plant_sunflower_adult
  • plant_potato_young and plant_potato_adult
  • plant_chili_young and plant_chili_adult
  • plant_broccoli_young and plant_broccoli_adult
  • plant_cauliflower_young and plant_cauliflower_adult
  • plant_melon_young and plant_melon_adult
  • plant_pea_young and plant_pea_adult
  • plant_salad_young and plant_salad_adult
  • plant_strawberry_young and plant_strawberry_adult

Missing Sprites:

  • plant_pumpkin_young
  • plant_pumpkin_adult

Data Flow

Planting → FarmManager Tracking → Growth Time → READY State →
  ↓
Render Attempt → TileLayer looks up farmingAssets.plant_pumpkin_adult →
  ↓
Asset Undefined → Silent Render Failure → Player can't see crop →
  ↓
getAvailableInteractions doesn't detect visible plot → No Harvest option

Required Changes

1. Asset Definition (assets.ts)

Add pumpkin crop sprite definitions to the farmingAssets object:

// In farmingAssets object, add:
plant_pumpkin_young: '/TwilightGame/assets-optimized/farming/pumpkin_young.png',
plant_pumpkin_adult: '/TwilightGame/assets-optimized/farming/pumpkin_adult.png',

Location: assets.ts - within the farmingAssets object definition, alphabetically near other crop sprites.

2. File Location References

The image files must exist at:

  • /public/assets-optimized/farming/pumpkin_young.png
  • /public/assets-optimized/farming/pumpkin_adult.png

These should be the hand-drawn pumpkin artwork files at 512×512px (per CLAUDE.md asset optimization guidelines).

Rendering Integration

The TileLayer rendering already has all necessary logic in place:

  • Line 67: Pumpkin adult size configuration ({ width: 2, height: 2, offsetX: -0.5, offsetY: -2 })
  • Lines 240-260: renderCrop() method that looks up farmingAssets['plant_' + cropType + '_young'] and farmingAssets['plant_' + cropType + '_adult']

Once assets are added, pumpkin crops will:

  1. Render as young seedling sprite (early growth stage)
  2. Render as adult 2×2 tile pumpkin sprite (mature, harvest-ready)
  3. Become detectable by getAvailableInteractions()
  4. Show harvest option in radial menu
  5. Allow harvesting with full gold rewards

Implementation Steps

  1. Verify asset files exist in /public/assets-optimized/farming/:

    • Check if pumpkin_young.png exists
    • Check if pumpkin_adult.png exists
    • If not, they must be created or sourced
  2. Update assets.ts:

    • Add plant_pumpkin_young asset definition in farmingAssets object
    • Add plant_pumpkin_adult asset definition in farmingAssets object
    • Ensure correct URL paths point to optimized assets
  3. No changes needed to:

    • data/crops.ts - Already properly configured
    • data/items.ts - Seed and crop items already defined
    • utils/farmManager.ts - Already handles all states correctly
    • utils/actionHandlers.ts - Already supports harvesting
    • utils/pixi/TileLayer.ts - Already has rendering logic and size config
  4. Verify by testing:

    • Plant pumpkin seeds on a farm plot
    • Wait for growth (20 minutes game time, or faster if watered)
    • Confirm pumpkin sprite appears and grows visually
    • Click on mature pumpkin plot
    • Confirm "Harvest Crop" option appears in radial menu
    • Harvest and collect pumpkins + gold

Testing

Manual Testing Checklist

  • Asset Loading

    • Open browser DevTools Network tab
    • Load game
    • Verify pumpkin_young.png and pumpkin_adult.png load successfully
    • No 404 errors for these assets
  • Planting

    • Acquire pumpkin seeds from shop or inventory
    • Select hoe tool and till soil
    • Select pumpkin seeds and plant
    • Plot transitions to SOIL_PLANTED state
  • Growth Visualization

    • Observe plot shows pumpkin_young sprite (seedling)
    • Water the crop
    • After ~14 minutes (watered growth time), plot should show pumpkin_adult sprite
    • Plot state transitions to SOIL_READY
  • Harvesting

    • Click on mature pumpkin plot
    • Radial menu appears with "Harvest Crop" option
    • Click harvest
    • "Harvested 1x Pumpkin (150 gold)" message in console
    • Inventory gains 1x crop_pumpkin
    • Player gains 150 gold
  • Adjacent Interaction

    • Plant new pumpkin
    • Wait for maturity
    • Click on adjacent tile (not directly on pumpkin)
    • Should still show harvest option
    • Harvest succeeds

Automated Testing

If visual inspection is needed, update tests/cropGrowth.test.ts:

  • Pumpkin tests already exist (lines with CROPS.pumpkin)
  • No changes needed - tests verify crop definition, not rendering

Risk Assessment

Risk Level: Very Low

  • ✅ Only affects asset definitions, no logic changes
  • ✅ All supporting systems already fully implemented
  • ✅ Follows established pattern used by 15+ other crops
  • ✅ No circular dependencies or SSoT violations
  • ✅ Assets are external files - no code compilation needed
  • ✅ No changes to GameState or core game loop

Failure Mode: If assets not found, TileLayer will fail silently (no visual render). User would see empty plot. No crashes or errors - graceful degradation. Harvest system would still work if debugging.

Related Issues

  • Similar to tomato setup (which works correctly)
  • Part of farming system expansion
  • Pumpkin data was added in recent commits but asset integration was incomplete

Future Considerations

  • Consider adding validation in assets.ts to warn if crop asset is missing
  • Add test to verify all crops in CROPS have corresponding rendering assets
  • Document asset requirements for new crops in CLAUDE.md

Next Steps

  1. Review the design document above
  2. Add the design-approved label to this issue to proceed to sprint planning
  3. Add the needs-revision label if changes are needed

Once approved, I'll automatically create a sprint plan for implementation.

@sunholo-voight-kampff sunholo-voight-kampff added the needs-design-approval Awaiting human approval of design document label Jan 22, 2026
@sunholo-voight-kampff

Copy link
Copy Markdown
Collaborator

Approval Complete - Work by TwilightGame Design Doc Creator approved.

Triggering next stage: twilight-sprint-planner

MarkEdmondson1234 pushed a commit that referenced this pull request Jan 27, 2026
## Summary
Move design document for defensive type checking in builtin implementations from planned to implemented, documenting the completed fix for:

1. String comparison type mismatch panic (Issue #1)
   - Fixed by adding SafeAsString() helper and updating string comparison builtins
   - Now returns descriptive errors instead of panicking

2. Option pattern matching failures (Issue #2)
   - Fixed by ensuring TaggedValue construction for Option types matches pattern matcher expectations
   - Now works correctly with Some(x) and None patterns

## Changes
- Move design_docs/planned/v0_7_0/m-builtin-safety-type-checks.md to
  design_docs/implemented/v0_7_0/m-builtin-safety-type-checks.md
- Update status from 'Planned' to 'Implemented'
- Add comprehensive implementation report with:
  - Code locations and metrics
  - Before/after comparison
  - Test coverage summary

## Test Results
✅ All builtin tests pass (PASS ok github.com/sunholo/ailang/internal/builtins)
✅ String comparison works correctly
✅ Option pattern matching works correctly
✅ No regressions in related functionality

## Verification
Tested with:
- String comparison: `substring(s, 0, length(prefix)) == prefix` ✓
- Option pattern matching: `match Some(x) { Some(h) => ..., None => ... }` ✓

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
sunholo-voight-kampff added a commit that referenced this pull request Mar 23, 2026
Updated 7 files to document the three-way import distinction:
  ./plan              — local sibling (same package)
  pkg/vendor/name/mod — external dependency
  std/module          — stdlib

Files updated:
- .claude/skills/ailang-packages/SKILL.md: Rule #2 rewritten for ./
- .claude/skills/ailang-packages/resources/error_solutions.md: LDR001 fix updated
- .claude/skills/ailang-packages/resources/manifest_reference.md: Import conventions section
- .claude/skills/use-ailang/resources/syntax_quick_ref.md: New Imports section
- docs/docs/guides/packages.md: Common Pitfalls #3 rewritten
- docs/docs/reference/modules.md: Import Syntax section with three forms
- changelogs/v0.9-current.md: M-DX-RELIMPORT entry in v0.9.12

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
sunholo-voight-kampff added a commit that referenced this pull request May 4, 2026
Round-1 sprint evaluation flagged three items (1 medium, 2 low). All three
addressed in this follow-up commit; no new design-doc deviations.

#1 (medium): Snapshot test for streaming-vs-non-streaming AI span shape
- New cmd/ailang/configdriven_streaming_span_snapshot_test.go (197 LOC)
- TestStreamingAISpan_SameShapeAsNonStreaming asserts that ctx.RecordAIEffect
  produces the same TraceEvent shape for "call" and "streamCall" — modulo
  OpName ("call" vs "streamCall") and Args content (1 vs 3 strings). Locks
  in the design-doc A4/A9 contract: streaming AI cannot silently degrade
  observability vs non-streaming AI.
- TestStreamingAISpan_RecordedFromAIStreamCallEndToEnd verifies the real
  aiStreamCall function reaches the recording call when invoked end-to-end
  against a mock SSE server. Belt-and-suspenders confirmation.

#2 (low): CapabilityNotSupported error code wiring
- Provider-registry misses (cmd/ailang/configdriven_streaming.go) now
  return ProtocolError("[ProviderNotFound] ...") rather than constructing
  a fake "ProviderNotFound" StreamErrorKind variant that wasn't in the
  declared ADT. Streaming-disabled / capabilities-streaming-false misses
  in BuildStreamRequest now carry "[CapabilityNotSupported]" prefix.
- Pattern: real StreamErrorKind variant + structured "[code]" prefix in
  the message string. Callers can pattern-match on ProtocolError AND
  switch on the [code] tag if needed. Documented inline.
- Tests updated to assert on (ProtocolError, [code] prefix) instead of
  fake-variant constructor names.

#3 (low): Recipe page pseudocode → concrete v1 snippet
- docs/docs/recipes/ai-token-streaming.md replaces the "pseudocode (v1.1
  will expose this via parseDelta)" block with a working v1 extractDelta
  template using std/json.decode and std/json.getString. Honest about the
  v1 limitation that std/json doesn't yet ship a path-walker — code shows
  the structural pattern callers should follow until v1.1's parseDelta.

All 6 packages still green: internal/pkg, internal/ai, internal/ai/configdriven,
internal/effects, internal/builtins, cmd/ailang. Full make test passes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
sunholo-voight-kampff added a commit that referenced this pull request May 8, 2026
…NGELOG

In-repo Pillar 2 work:
  - docker/Dockerfile.agent-motoko: clones sunholo-data/motoko_agent at
    pinned commit 84fa449, installs bun + motoko-ext-* packages,
    symlinks scripts/run-agent.sh to /usr/local/bin/motoko. Mirrors
    Dockerfile.agent-pi (CLI-only, no Go toolchain).
  - internal/dispatch/cloudrun/dispatcher.go: knownVariants["motoko"]=true.
  - docker/agent-motoko-multivac-prs.md: step-by-step checklist for the
    two ailang-multivac PRs (cloudbuild + cloudbuild-images sync per
    EXECUTOR_SHAPE §6 drift warning; agent_executor_motoko Cloud Run
    Job with cost-controlled secret bindings — OPENROUTER + OPENAI +
    GEMINI only, NO ANTHROPIC per pi precedent).

Cross-repo work (NOT in this commit, requires ailang-multivac access):
  - PR #1 to ailang-multivac: cloudbuild.yaml + cloudbuild-images.yaml
    add build-agent-motoko + push-agent-motoko steps (in BOTH files).
  - PR #2 to ailang-multivac: terraform/cloud_run_jobs.tf adds
    agent_executor_motoko block with VPC connector + cost-controlled
    env bindings. Smoke test: terraform apply to ailang-multivac-dev,
    coordinator dispatch with --executor motoko.

M5 (threshold measurement) is queued — requires either the cloud Job
above or a local run with OPENROUTER_API_KEY budget. The eval-suite
command is documented in the CHANGELOG entry; numbers will be appended
under a follow-up entry once data exists.

Tests: full go test ./... green; whole-tree builds clean.

Closes M4 of M-MOTOKO-EXECUTOR-ADAPTER (in-repo portion). M5 deferred
to follow-up after cloud Job lands or local run executes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sunholo-voight-kampff added a commit that referenced this pull request May 8, 2026
Previously pkg.ResolveDependencies was used to find toInterfaceHash,
but a package can't find itself in its own resolved deps (case A) and
a consumer's manifest doesn't trigger the branch at all (case B).

Fix: case A (running from the package dir) calls pkg.InterfaceHash
directly; case B (running from a consumer with a path dep) walks
manifest.Dependencies, loads the dep manifest from its local path,
and calls pkg.InterfaceHash on it.

The entire motoko-ext-* fleet can now fire upgrade-available messages
without manual JSON workarounds (msg 4a16ab61 issue #2).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sunholo-voight-kampff added a commit that referenced this pull request May 8, 2026
… 10 integration gaps

Today's live smoke testing of v0.18.0's M-MOTOKO-EXECUTOR-ADAPTER
surfaced 10 interconnected gaps that prevent trustworthy benchmark
numbers. Three got partial fixes during the day (HealthCheck no-spawn,
MOTOKO_REPO fallback, MOTOKO_HEADLESS, run_summary-before-done reorder)
but root causes remain across both repos. User feedback: "we need it
all I think. lets get to the bottom of the gaps - I think a design
doc process will help."

This sprint sequences the fixes properly:

  Phase 1: Investigation-first for gap #1 (run_summary not reaching
    disk on success path) — debug:checkpoint markers + bisect.
    Non-negotiable; writing a fix without the cause is gambling.

  Phase 2: motoko-side fixes (gap #1 root-cause fix + #6 extension
    visibility + #7 --headless flag + #8 --version mode + #10 TS
    process.exit removal so emission ordering doesn't matter)

  Phase 3: AILANG-side fixes (gap #2 success-criteria fallback to
    thinking.finish_reason + #5 MOTOKO_REPO discovery from wrapper)

  Phase 4: Cross-cutting (gap #4 session_id unification — adapter
    canonical, TS wrapper honors, AILANG runtime emits matching)

  Phase 5: Config layer (gap #3 + #9 cost_rates source-of-truth in
    models.yml.pricing → env-var override of motoko's profile config)

  Phase 6: End-to-end validation — TestEndToEnd_FullResultPopulation
    asserts every Result field; M5 paired-comparison
    motoko-claude-haiku-4-5 vs claude-haiku-4-5 produces real numbers.

Architectural posture: eliminate fragile assumptions at every layer.
Today's adapter assumes things that aren't true (wrapper preserves
session_id, cost_rates configured, run_summary always reaches disk,
loaded_extensions field accurate). After this hardening, none of those
assumptions remain — each replaced with explicit observable contracts.

Net axiom score: +13 (no hard violations). Strong A2 (replayability —
captured runs are fully reproducible), A7 (machines first — Result
fields mechanically reliable), A9 (cost visibility — eliminates $0
reporting gap).

Estimated 3 working days, ~530 LOC including tests, across both repos.
GATING for M5 of v0.18.0 (threshold-measurement) and v0.19.0
M-MOTOKO-EXT-PER-TASK (which needs accurate session_ids + extension
visibility from this hardening).

Cross-references:
- v0.18.0 M-MOTOKO-EXECUTOR-ADAPTER Future Work updated to point at
  this hardening as the trustworthy-numbers prerequisite
- v0.19.0 M-MOTOKO-EXT-PER-TASK Dependencies updated to mark v0.18.1
  as BLOCKING (was just "after local validation")

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sunholo-voight-kampff added a commit that referenced this pull request May 8, 2026
…a-c, gaps #2 #5)

Phase 3 of v0.18.1 hardening sprint. Closes gap #2 (success-criteria
gated on run_summary presence) and gap #5 (MOTOKO_REPO discovery).

M3a — Truncated-success fallback (gap #2)
==========================================
Pre-M1c, the JSONL frequently truncated before run_summary reached disk
(TS process.exit-on-done dropped the WriteStream buffer). The parser was
setting Success=false in that case, mis-attributing successful runs as
crashes. Even after M1c reliably flushes run_summary, future truncation
classes (network drop, disk full, signal kill mid-flush) can recur.

New three-way classification when run_summary is absent:
  - gotErrorEvent          → Success=false, error message from event
  - lastFinishReason="stop" → Success=true (truncated-but-complete)
  - else                    → Success=false (likely crash)

When the truncated-but-complete branch fires, two ProviderData signals
are added so consumers can tell this case apart from a clean run:
  - motoko_run_summary_missing: true
  - motoko_finish_reason: "stop"

Without this fallback, the eval harness would systematically under-report
the success rate of any motoko version pre-M1c (or any future version
that hits a similar tail-truncation bug). With it, the truth is preserved
even when the JSONL stream loses its tail.

M3b — MOTOKO_REPO discovery (gap #5)
=====================================
findSessionJSONL now takes a third arg `discoveredRepo`. The lookup chain:
  1. <workspace>/.motoko/logfile/<sessionID>.jsonl
  2. <MOTOKO_REPO env>/.motoko/logfile/...    (env wins when set)
  3. <discoveredRepo>/.motoko/logfile/...     (M2c HealthCheck output)

discoveredRepo is populated by HealthCheck via `motoko --version` parsing
(M2c). This closes the zero-config requirement: an operator can now
`go run ./cmd/smoke-motoko` without setting MOTOKO_REPO at all. The
adapter queries the binary for its install location and finds the JSONL
there.

Operator override semantics preserved: explicit MOTOKO_REPO env beats
discovered every time. Discovery is the safety net, not the policy.

M3c — Parser tests
==================
Three new tests:
  - TestParseSessionJSONL_TruncatedSuccess: covers the M3a fallback
  - TestFindSessionJSONL_DiscoveredRepoFallback: covers M3b zero-config
  - TestFindSessionJSONL_EnvWinsOverDiscovered: locks in env-precedence

New fixture session_no_summary_truncated_success.jsonl: a 2-step run
that ends mid-flush after the final thinking event with finish_reason=
"stop" but no run_summary or done. Realistic shape (matches what we
observed from real motoko runs pre-M1c).

Also extracts a `motokoStateDir = ".motoko"` const to retire SonarQube's
"don't repeat string literal" warning across the 4 occurrences.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sunholo-voight-kampff added a commit that referenced this pull request May 8, 2026
…design docs

Phase 6 of v0.18.1 hardening sprint.

Moves both design docs from design_docs/planned/v0_18_1/ to
design_docs/implemented/v0_18_1/ and updates their status headers to
"Implemented (2026-05-08)" with cross-repo commit references.

Adds the v0.18.1 entry to changelogs/v0.10-current.md covering all
five phases:
  - Phase 1 (gap #1): JSONL drain race in TS layer
  - Phase 2 (gaps #6, #7, #8): extensions visibility, --headless, --version
  - Phase 3 (gaps #2, #5): success fallback, MOTOKO_REPO discovery
  - Phase 4 (gap #4): session_id unification
  - Phase 5 (gaps #3, #9): cost rates env-var passthrough

Acceptance gate: 5 of 7 conditions met; the remaining 2 (CostUSD>0
end-to-end + smoke success) blocked on a separate Bedrock validation
issue (extension tool names with `/` fail Anthropic's
^[a-zA-Z0-9_-]{1,128}$ pattern). The pricing env-var plumbing is
verified by unit tests; live smoke needs the extension fix downstream.

LOC tally: ~80 AILANG-side + ~250 motoko-side + 11 new tests across
both repos, in ~6 hours wall-clock vs the 3-day plan estimate.

Sprint retrospective: investigation-first paid off — the 12 debug:
checkpoint markers in Phase 1 directly identified the silent-exit
point as the TS process.exit-on-done race, which would have been
maddening to find by code-reading alone. The resulting fix was tiny
(~25 LOC across 2 TS files) but unblocked everything downstream.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
MarkEdmondson1234 pushed a commit that referenced this pull request May 19, 2026
…ows CI fixes

Addresses the two low-severity follow-up items from the round-1
sprint-evaluator verdict (PASS @ 91/100) plus Windows CI test flakes
the user surfaced.

cmd/wasm/effects.go (266 LOC removed) + effects_cognition.go (290 LOC, new):
- Extract WasmDOMHandler + WasmMsgHandler + setDOM*/setMsg* + getOrCreate*
  + domPatchToJS into a dedicated file so each module stays under the
  800-line AI-maintainability threshold
- cmd/wasm/effects.go drops from 918 → 652 LOC (back under threshold)
- effects_cognition.go is build-tagged js && wasm same as the original
- Shared helpers (awaitJSResult, jsGetString, jsGetInt, replInstance)
  continue to live in effects.go / effects_helpers.go — same package,
  so the split is purely organizational

docs/docs/guides/wasm-integration.md (+108 LOC):
- New "Cognitive OS Substrate (v0.21.x)" section covering: shipped
  effects (DOM/Msg/Trace), step-pattern interface, cognitive event
  log + replay determinism claim, JS API for the bridges, runnable
  example pointer, end-to-end status table separating shipped vs
  deferred items across M-COG-RUNTIME / M-COG-RUNTIME-BROWSER /
  M-COG-MEMORY / M-COG-MESH
- The sprint plan named docs/docs/guides/wasm-runtime.md as the
  target; the actual existing guide is wasm-integration.md, so the
  section is added there

Windows CI test fixes (two flakes the user surfaced):

cmd/ailang/main_run_pipe_test.go (+8 LOC):
- TestRunCommand_PipedStdoutFlushesPerLine was failing on
  windows-latest with "EVENT_1 arrived at 1.6967s — too late". The
  load-bearing gap assertion (EVENT_1 → EVENT_2 ≥ 200ms) passed; only
  the belt-and-suspenders absolute-time check failed because the
  ailang binary cold-start cost on Windows runner VMs is ~1.7s vs
  <0.5s on Linux/macOS
- Fix: scale the upper bound to 3.5s on Windows via runtime.GOOS
- The gap check remains the load-bearing assertion at 200ms

internal/lsp/diagnostics_test.go (+19 / -6 LOC):
- TestDidSaveRepublishes was failing on windows-latest with
  "no diagnostics arrived after didSave" (5s timeout). LSP pipeline
  latency on Windows runners exceeds the 5s budget that works locally
- Fix: new diagWaitTimeout() helper returns 15s on Windows, 5s
  elsewhere; all four sink.wait(docURI, 5*time.Second) sites updated
- Server lifecycle context bumped to 3× the diag wait so the parent
  context doesn't expire while a wait is still in flight on Windows

Both tests pass locally (Linux/macOS) post-change. The Windows budgets
preserve test intent (verify streaming / verify republish) without
turning either test into a no-op.

Refs:
  .ailang/state/evaluations/eval_M-COG-RUNTIME_round_1.json (feedback items #1, #2)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
sunholo-voight-kampff added a commit that referenced this pull request May 24, 2026
M-AILANG-ERROR-QUALITY iter 4 (compiler error-msg #2): the dense_operator_program
benchmark has consistently failed (0/4 across all baseline rotations) because
gemma4-class models write `a | b` expecting bitwise OR. The previous parser
error said only "unexpected token in expression: |" + "This token cannot
start an expression" — true but unactionable; the agent thrashes for 17+
to 75 turns without finding the right syntax.

New PAR016 error includes:
  - Explicit statement that `|` is reserved for `match` pattern alternatives
  - The full list of AILANG bitwise operators (&, ^, ~, <<, >>) so the agent
    sees what IS available
  - The De Morgan's-law identity (`~(~a & ~b)` computes bitwise OR) as the
    explicit workaround since AILANG has no bitwise OR token
  - The `||` clarification for logical OR (boolean context)
  - The pattern-alternative usage example for `match`

The slim-v2 prompt added this same guidance prose-side; Iter 2 showed that
DID move the agent from FAIL/thrash to compile_ok=true (just runtime_error
still). This compiler-side fix should help the agent reach the same insight
faster, regardless of which prompt version is active.

Live verification: `ailang check` on test file with `let x = 5 | 3 in ...`
now emits PAR016 with all 4 suggestions + docs link. Build + full make ci
pass (44s). No test changes needed because previous behavior emitted
PAR_NO_PREFIX_PARSE which we still emit as a fallback for non-PIPE tokens.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
sunholo-voight-kampff added a commit that referenced this pull request May 27, 2026
…oss-repo PR checklist v0.23.0 refresh

In-repo changes (the only M3 work that ships in this commit — the rest
lives in ailang-multivac):

1. cloudbuild-dev.yaml gains `build-agent-motoko` step mirroring
   `build-agent-go` (registry-cached buildx, FROMs agent-base via
   Dockerfile.agent-motoko's existing FROM). Push happens via
   `--push` flag like the other agent-* builders. `deploy-services`
   waitFor now includes build-agent-motoko so the deploy step doesn't
   race ahead of the image being available.

2. docker/agent-motoko-multivac-prs.md refreshed for v0.23.0 scope:
   - NEW: PR #0 (operational) — cloud `ailang-coordinator` is on a
     2026-04-28 image (pre-v0.21.0); MUST redeploy before E2E can
     exercise the v0.22.0 `requires` field
   - PR #2 addendum — coordinator agent config (config.yaml in the
     mounted ConfigMap) needs `motoko` agent entry with `worker_tags:
     [agent:motoko]` so M-COORD-MULTI-HOST-WORKERS tag matcher
     recognises the cloud Job as a valid dispatch target
   - PR #2 Job spec gets `max_retries = 1` (motoko is non-idempotent
     in cost — one retry max)
   - PR #3 (NEW, deferred) — `ailang-openrouter-api-key` prod secret
     resource. Currently only ailang-multivac-DEV has the secret;
     prod motoko cloud-dispatch is gated on cost analysis from dev
     throughput. Per-Job $0.30 cap on `motoko-or-gemma-4-26b` bounds
     the blast radius.
   - End-to-end smoke command updated to use the new --requires CLI
     flag from M2 (closes the v0.22.0 CLI gap that necessitated
     curl POST workarounds)

Acceptance gate refresh: 5 items, including the PR #0 pre-flight
("coordinator image timestamp shows post-v0.22.0 deploy").

What's NOT in this commit (intentional — cross-repo):
- The ailang-multivac terraform/cloud_run_jobs.tf addition (PR #2 body)
- The mounted coordinator config update (PR #2 addendum body)
- The prod secret resource (PR #3, deferred)
- The ailang-multivac cloudbuild.yaml + cloudbuild-images.yaml updates (PR #1)

Lints clean. cloudbuild-dev.yaml YAML validates (10 steps, build-agent-motoko
inserted between build-agent-go and push-coordinator).

Refs: M-COORD-MULTI-HOST-WORKERS Future Work item #1 (cloud-fallback
routing) — the local-side closures landed in M1/M2; this completes the
in-repo half of the cross-repo cloud-side work.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
sunholo-voight-kampff added a commit that referenced this pull request May 27, 2026
…trix

Three docs updates:

1. changelogs/v0.10-current.md: comprehensive sprint entry covering
   M1 (launchd PORT + status probe), M2 (--requires CLI flag),
   M3 (in-repo half of cloud-fallback: cloudbuild step + cross-repo
   PR checklist). Explicit verification matrix shows what works locally
   versus what's gated on the cross-repo / cross-deploy PRs:
     - Scenario 1 (Studio→Studio): partial — HTTP send path verified
       (M2 live smoke), but local dispatcher's requires-aware executor
       selection is a follow-up
     - Scenario 2 (laptop→cloud→Studio): deferred — gated on PR #0
       (cloud coordinator redeploy from April-28 image)
     - Scenario 3 (cloud-fallback Job): deferred — gated on PRs #1+#2
       in ailang-multivac

2. docs/docs/guides/coordinator-workers.md: refreshed Example 2 with
   the new `--requires` CLI invocation (replaces hand-rolled curl);
   added "HTTP endpoint configuration" subsection (default port 8765,
   override via env or --port flag, /health probe, route catalog with
   per-route auth requirements + warning about exposing :8765 without
   COORDINATOR_API_KEY).

3. docs/docs/guides/agent-messaging.md: new "Tag-routed sends (v0.23.0+)"
   subsection with concrete --requires examples (single tag, multi-tag
   intersection) + prerequisites callout (HTTP listener up, worker
   advertising the tag set).

Honest accounting: the local-side surface (M1+M2) is feature-complete
and ready for use today. The cloud-side dispatch path (M3.x in
ailang-multivac repo) is documented but not in production. The
sprint plan called this out as expected — the in-repo half is what
ships in v0.23.0; the cross-repo PRs are tracked separately.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
sunholo-voight-kampff added a commit that referenced this pull request May 27, 2026
…ed/v0_23_0/

Sprint complete: 4/4 milestones pass.

In-repo shipped:
- M1: launchd PORT env + status probe (commit 49664aa, 86 LOC)
- M2: --requires CLI flag + 4 tests (commit 9544139, 274 LOC)
- M3: cloudbuild build-agent-motoko + cross-repo PR checklist (commit
  e4df2f4, 135 LOC)
- M4: docs + CHANGELOG + verification matrix (commit 012cf39, 101 LOC)

Total: 596 LOC actual vs 305 estimated (overshot — docs heavier than
the design doc accounted for, and the cross-repo PR checklist refresh
in M3 was richer than a thin update).

Verification matrix (honest):
- Scenario 1 (Studio→Studio): partial — HTTP send verified live; local
  dispatcher's requires-aware executor selection is a follow-up
- Scenario 2 + 3: deferred on the cross-repo PRs documented in
  docker/agent-motoko-multivac-prs.md (PR #0/#1/#2 in ailang-multivac
  repo, plus the operational cloud coordinator redeploy)

The local-side surface (M1+M2) is feature-complete and ships in v0.23.0.

Next: hand off to sprint-evaluator.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
sunholo-voight-kampff added a commit that referenced this pull request May 28, 2026
…re engine call

makeToolHandler bound a declared param the client omitted (absent key) or sent
as JSON null to nil, which the engine turned into Unit; the AILANG function then
crashed deep in stdlib (e.g. _str_len: expected String, got Unit) with no
actionable message. Presence-check declared params and return a structured
"missing required parameter(s): <names>" error (isError=true, declaration order)
before CallPreserveFloats. Type-agnostic — an omitted int rejects the same as a
string. Legacy positional {"args":[...]} opts out of named binding, unaffected.

@route audit (per CLAUDE.md systemic-fix rule): confirmed NOT the same bug. The
@route path zero-pads omitted typed params via zeroValueForType (""/0/false/[]/{}),
never nil->Unit for known types — the deliberate v0.21.0 m-serveapi-get-query-shadow
design that lets handlers self-validate. Added TestRouteParamOmission_ZeroPadsNotNil
as a regression guard for that invariant; documented both behaviors and why they
diverge in serve-api.md.

6 new tests in mcp_param_binding_test.go pass -count=20 (4 reject cases incl.
explicit-null + deterministic multi-missing order; 2 regression cases that invoke
the real engine on a loaded module).

Refs #2, #243, #258

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
sunholo-voight-kampff added a commit that referenced this pull request May 28, 2026
Combined [Unreleased] changelog entry covering M1 (std/ai.callJsonSimpleResult)
and M2 (MCP omitted/null param rejection + @route audit), referencing the docparse
source messages (623811a0, b08617cb). Moved both design docs (status -> Implemented)
and the sprint plan (status -> Completed) from planned/v0_23_0 to implemented/v0_23_0.

Resolution replies sent to the docparse inbox for both source reports. make test +
make lint clean (the 4 'unused' lint findings are pre-existing in
internal/executor/managed_agents/ from v0.22.0, untouched here).

Refs #2, #243, #258

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
sunholo-voight-kampff added a commit that referenced this pull request May 29, 2026
Bundles all unreleased work since v0.22.0 (30 commits, 5 sprints):
- M-COORD-TAG-ROUTING-LASTMILE: tag-routed `messages send --requires`
- M-DOCPARSE-RESILIENCE-FIXES: std/ai.callJsonSimpleResult + MCP omitted/null
  param rejection (resolves docparse reports 623811a0, b08617cb)
- M-MSG-TRIAGE-ROUTER: inbound bug/feature auto-promotion to design-doc-creator
- M-NOTIFY-CHANNELS + M-NOTIFY-FANOUT: outbound notification framework + Discord
- plus M-EXECUTOR-VARIANTS, M-BENCHMARK-SECTION-REDESIGN, M-EVAL-LANG-JSGO,
  M-MICRORAG-EXPAND

Relabeled the notify/triage entries from v0.24.0 to v0.23.0 (bundled into this
release per release-scope decision); their multi-phase design docs remain in
planned/v0_24_0 since later phases target the next release.

Refs #2, #243, #258

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
sunholo-voight-kampff added a commit that referenced this pull request Jun 10, 2026
Frequency analysis of 334 local-qwen agent trials (44 failures) shows ~36% are
a single family — expression-body (= expr) vs block-body ({ stmts }) /
statement-separator confusion — dominated (20.5%) by the
`func f() = let x = e; rest` reflex (PAR017: ';' not valid in expression-body
functions). match...with (PAR019) and ++-for-string-concat — the old big-model
top failures — are now rare/zero on qwen, so the card already works for those;
the small-model frequency banners undercount what's still live.

- Sharpen dialect-traps card trap #2 to name the exact `= let x = e; rest`
  anti-pattern + both fixes (brace block, or let-in). Verified: anti-pattern
  rejects (PAR017), both fixes run.
- Record the local-qwen frequency data in m-ailang-error-quality-for-llm-iteration
  (re-prioritizes it): parser/card already cover PAR017 yet the model fails it and
  can't recover (config_file_parser thrashed 66 turns) — the lever is making PAR017
  recovery-actionable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

coordinator:in-progress Task claimed by a coordinator instance - prevents duplicate work needs-design-approval Awaiting human approval of design document

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants