diff --git a/.claude/skills/porting-to-canyonos/SKILL.md b/.claude/skills/porting-to-canyonos/SKILL.md index 7d4a092b..a4be1df0 100644 --- a/.claude/skills/porting-to-canyonos/SKILL.md +++ b/.claude/skills/porting-to-canyonos/SKILL.md @@ -21,7 +21,7 @@ Copy this checklist into the response and update it while working: Port progress: - [ ] 1. Prepare `.car` - [ ] 2. Survey the copy and choose service boundaries -- [ ] 3. Write adapters, workflow, declarations, and reviewed configuration +- [ ] 3. Write adapters, workflow, test input, declarations, and reviewed configuration - [ ] 4. Gap validation exits 0; report readiness and stop ``` diff --git a/.claude/skills/porting-to-canyonos/references/adapter.md b/.claude/skills/porting-to-canyonos/references/adapter.md index 4fbb841c..2e8c953b 100644 --- a/.claude/skills/porting-to-canyonos/references/adapter.md +++ b/.claude/skills/porting-to-canyonos/references/adapter.md @@ -3,8 +3,9 @@ **When:** after selecting service boundaries, before writing an adapter or workflow. -**Output:** one loadable adapter per service and one workflow exposing -`main(query: str)`. +**Output:** one loadable adapter per service, one workflow exposing +`main(query: str)`, and `.car/config/test_query.txt` holding one input that +workflow accepts. Use this order: @@ -12,6 +13,7 @@ Use this order: 2. Write a no-argument synchronous adapter around source-owned behavior. 3. Bridge async or session state only when the source requires it. 4. Write the workflow and preserve parallel dispatch. +5. Write the workflow's test input. Complete `manifest.md`, then validate only the authored contracts that CanyonOS does not already guarantee. @@ -22,6 +24,7 @@ only when a container loads. ## Contents - Adapter and workflow shape +- Workflow input and its test case - Choosing the entrypoint - Bridging async - Multi-turn and session state @@ -55,6 +58,20 @@ results = [json.loads(future.value()) for future in futures] Combining dispatch and `.value()` in one comprehension serializes the work. +## Workflow input and its test case + +`query` is always a `str`. Parse richer input out of it inside `main` +(`int(query)`, `json.loads(query)`). Future arguments and `.value()` results +are also text; the yaml `type` does not coerce them. + +Write one eligible input to `.car/config/test_query.txt`: the required input +only, taken from the source, with no comments, quotes, or `{"query": ...}` +wrapper. End-to-end testing sends it verbatim: + +```bash +canyonos test "$(cat .car/config/test_query.txt)" +``` + ## Choosing the entrypoint The entrypoint is the one module in the copy the build destroys: each agent's diff --git a/.claude/skills/porting-to-canyonos/references/preparation.md b/.claude/skills/porting-to-canyonos/references/preparation.md index 3f785ffc..a495ba26 100644 --- a/.claude/skills/porting-to-canyonos/references/preparation.md +++ b/.claude/skills/porting-to-canyonos/references/preparation.md @@ -33,6 +33,7 @@ The port lives entirely inside `.car/`, next to the application source: .car/config/global_controller.yaml deployment manifest .car/config/policy.yaml optional access restriction .car/config/.yaml one callable surface per service +.car/config/test_query.txt one eligible workflow input, verbatim .car/app/ a copy of the application source .car/app//.py adapter beside the code it wraps .car/app//_workflow.py HTTP entry point; calls deploy() diff --git a/.claude/skills/porting-to-canyonos/validation/dependencies.py b/.claude/skills/porting-to-canyonos/validation/dependencies.py index 3a469c93..5a9006c2 100644 --- a/.claude/skills/porting-to-canyonos/validation/dependencies.py +++ b/.claude/skills/porting-to-canyonos/validation/dependencies.py @@ -178,7 +178,7 @@ def check_requirements_coverage( f"something other than `{name}`, declare that name in " f"{report.rel(config_path)}." ) - report.error( + report.warn( "W006", where, lineno,