microduck-cli 0.9.6__tar.gz → 0.9.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/operate-microduck/SKILL.md +10 -0
- microduck_cli-0.9.7/.devague/current +1 -0
- microduck_cli-0.9.7/.devague/current_plan +1 -0
- microduck_cli-0.9.7/.devague/frames/run-trace-tool.json +584 -0
- microduck_cli-0.9.7/.devague/plans/run-trace-tool.json +518 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/CHANGELOG.md +17 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/CLAUDE.md +48 -5
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/PKG-INFO +7 -1
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/README.md +6 -0
- microduck_cli-0.9.7/docs/deliveries/2026-09-08-run-trace-tool.md +101 -0
- microduck_cli-0.9.7/docs/plans/2026-09-08-run-trace-tool.contract.md +83 -0
- microduck_cli-0.9.7/docs/plans/2026-09-08-run-trace-tool.md +98 -0
- microduck_cli-0.9.7/docs/specs/2026-09-08-run-trace-tool.md +122 -0
- microduck_cli-0.9.7/docs/traces/2026-09-08-spark-tutorial/events.jsonl +995 -0
- microduck_cli-0.9.7/docs/traces/2026-09-08-spark-tutorial/index.html +694 -0
- microduck_cli-0.9.7/docs/traces/2026-09-08-spark-tutorial/meta.json +128 -0
- microduck_cli-0.9.7/docs/traces/2026-09-08-spark-tutorial/shots/s0-seated.jpg +0 -0
- microduck_cli-0.9.7/docs/traces/2026-09-08-spark-tutorial/shots/s1-init-ramp.jpg +0 -0
- microduck_cli-0.9.7/docs/traces/2026-09-08-spark-tutorial/shots/s10-engine.jpg +0 -0
- microduck_cli-0.9.7/docs/traces/2026-09-08-spark-tutorial/shots/s11-before-down.jpg +0 -0
- microduck_cli-0.9.7/docs/traces/2026-09-08-spark-tutorial/shots/s2-stand-1.jpg +0 -0
- microduck_cli-0.9.7/docs/traces/2026-09-08-spark-tutorial/shots/s3-stand-2.jpg +0 -0
- microduck_cli-0.9.7/docs/traces/2026-09-08-spark-tutorial/shots/s4-look.jpg +0 -0
- microduck_cli-0.9.7/docs/traces/2026-09-08-spark-tutorial/shots/s5-roulade-a.jpg +0 -0
- microduck_cli-0.9.7/docs/traces/2026-09-08-spark-tutorial/shots/s6-roulade-b.jpg +0 -0
- microduck_cli-0.9.7/docs/traces/2026-09-08-spark-tutorial/shots/s7-after-roulade.jpg +0 -0
- microduck_cli-0.9.7/docs/traces/2026-09-08-spark-tutorial/shots/s8-move.jpg +0 -0
- microduck_cli-0.9.7/docs/traces/2026-09-08-spark-tutorial/shots/s9-after-move.jpg +0 -0
- microduck_cli-0.9.7/docs/traces/2026-09-08-spark-tutorial/trace.html +691 -0
- microduck_cli-0.9.7/docs/traces/tutorial.sidecar.toml +71 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/cli/__init__.py +4 -2
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/cli/_commands/learn.py +3 -2
- microduck_cli-0.9.7/microduck_cli/cli/_commands/trace.py +689 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/explain/catalog.py +23 -4
- microduck_cli-0.9.7/microduck_cli/explain/trace.py +312 -0
- microduck_cli-0.9.7/microduck_cli/trace/__init__.py +18 -0
- microduck_cli-0.9.7/microduck_cli/trace/capture.py +470 -0
- microduck_cli-0.9.7/microduck_cli/trace/events.py +763 -0
- microduck_cli-0.9.7/microduck_cli/trace/plan.py +471 -0
- microduck_cli-0.9.7/microduck_cli/trace/render.py +513 -0
- microduck_cli-0.9.7/microduck_cli/trace/runner.py +546 -0
- microduck_cli-0.9.7/microduck_cli/trace/serve.py +137 -0
- microduck_cli-0.9.7/microduck_cli/trace/template.html +688 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/pyproject.toml +1 -1
- microduck_cli-0.9.7/tests/fixtures/trace_events_missing_lane.jsonl +2 -0
- microduck_cli-0.9.7/tests/fixtures/trace_events_valid.jsonl +5 -0
- microduck_cli-0.9.7/tests/fixtures/trace_import_src/events.jsonl +2 -0
- microduck_cli-0.9.7/tests/fixtures/trace_import_src/shots/frame1.jpg +1 -0
- microduck_cli-0.9.7/tests/test_cli_trace.py +864 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_lockstep.py +2 -2
- microduck_cli-0.9.7/tests/test_trace_capture.py +586 -0
- microduck_cli-0.9.7/tests/test_trace_events.py +616 -0
- microduck_cli-0.9.7/tests/test_trace_example.py +45 -0
- microduck_cli-0.9.7/tests/test_trace_plan.py +502 -0
- microduck_cli-0.9.7/tests/test_trace_render.py +423 -0
- microduck_cli-0.9.7/tests/test_trace_runner.py +371 -0
- microduck_cli-0.9.7/tests/test_trace_serve.py +126 -0
- microduck_cli-0.9.7/tests/test_trace_sidecar.py +89 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/uv.lock +1 -1
- microduck_cli-0.9.6/.devague/current +0 -1
- microduck_cli-0.9.6/.devague/current_plan +0 -1
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/agent-config/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/agent-config/data/backend-fingerprints.yaml +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/agent-config/scripts/show.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/ask-colleague/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/ask-colleague/prompts/explore.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/ask-colleague/prompts/review.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/ask-colleague/prompts/write.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/ask-colleague/scripts/ask-colleague.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/assign-to-workforce/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/challenge/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/cicd/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/cicd/scripts/_resolve-nick.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/cicd/scripts/portability-lint.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/cicd/scripts/pr-reply.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/cicd/scripts/pr-status.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/cicd/scripts/workflow.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/communicate/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/communicate/scripts/fetch-issues.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/communicate/scripts/mesh-message.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/communicate/scripts/post-comment.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/communicate/scripts/post-issue.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/communicate/scripts/templates/skill-new-brief.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/communicate/scripts/templates/skill-update-brief.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/deviate/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/pypi-maintainer/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/pypi-maintainer/scripts/switch-source.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/recall/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/recall/scripts/recall.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/remember/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/remember/scripts/remember.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/run-tests/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/run-tests/scripts/test.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/scope/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/sonarclaude/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/sonarclaude/scripts/sonar.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/spec-to-plan/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/spec-to-plan/scripts/spec-to-plan.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/summarize-delivery/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/think/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/think/scripts/think.sh +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/validate-delivery/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/version-bump/SKILL.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills/version-bump/scripts/bump.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.claude/skills.local.yaml.example +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.devague/deliveries/jetson-retest-and-ai-lab-tutorial.json +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.devague/deliveries/microduck-cli-env-teach-operate-rules.json +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.devague/deliveries/orin-sanity.json +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.devague/deliveries/readme-as-proof.json +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.devague/deliveries/thor-sanity.json +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.devague/frames/jetson-retest-and-ai-lab-tutorial.json +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.devague/frames/microduck-cli-env-teach-operate-rules.json +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.devague/frames/orin-sanity.json +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.devague/frames/readme-as-proof.json +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.devague/frames/thor-sanity.json +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.devague/plans/jetson-retest-and-ai-lab-tutorial.json +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.devague/plans/microduck-cli-env-teach-operate-rules.json +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.devague/plans/orin-sanity.json +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.devague/plans/readme-as-proof.json +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.devague/plans/thor-sanity.json +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.eidetic/memory/microduck-cli__public.jsonl +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.flake8 +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.github/workflows/publish.yml +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.github/workflows/tests.yml +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.gitignore +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/.markdownlint-cli2.yaml +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/AGENTS.colleague.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/LICENSE +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/culture.yaml +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/deliveries/2026-09-03-microduck-cli-env-teach-operate-rules.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/deliveries/2026-09-04-orin-sanity.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/deliveries/2026-09-04-readme-as-proof.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/deliveries/2026-09-07-jetson-retest-and-ai-lab-tutorial.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/operating-the-duck.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/plans/2026-09-03-microduck-cli-env-teach-operate-rules.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/plans/2026-09-04-orin-sanity.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/plans/2026-09-04-thor-sanity.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/plans/2026-09-07-jetson-retest-and-ai-lab-tutorial.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/skill-sources.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/specs/2026-09-03-microduck-cli-env-teach-operate-rules.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/specs/2026-09-04-orin-sanity.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/specs/2026-09-04-readme-as-proof.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/specs/2026-09-04-thor-sanity.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/specs/2026-09-07-jetson-retest-and-ai-lab-tutorial.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/tools/check_tutorial.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/upstream-pins.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/verification/2026-09-04-orin-sanity.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/verification/2026-09-04-sim-bringup.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/verification/2026-09-04-thor-sanity.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/verification/2026-09-07-spark-retest.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/docs/verification/2026-09-08-thor-orin-tutorial-run.md +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/__init__.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/__main__.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/__init__.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/compose.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/default_rules.toml +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/defaults.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/engine.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/human_gate.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/idle.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/intents.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/liveness.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/model.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/release.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/replay.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/rule_engine.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/rules.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/sense.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/senselog.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/sink.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/behavior/skills.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/cli/_commands/__init__.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/cli/_commands/cli.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/cli/_commands/doctor.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/cli/_commands/duck.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/cli/_commands/env.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/cli/_commands/explain.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/cli/_commands/overview.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/cli/_commands/policy.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/cli/_commands/rules.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/cli/_commands/whoami.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/cli/_errors.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/cli/_output.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/duck/__init__.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/duck/addressing.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/duck/gate.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/duck/record.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/env/__init__.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/env/doctor.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/env/hosts.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/env/params.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/env/stack.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/explain/__init__.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/explain/duck.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/explain/env.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/explain/policy.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/explain/rules.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/ipc/__init__.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/ipc/client.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/ipc/proto.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/train/__init__.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/train/artifacts.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/microduck_cli/train/lane.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/sonar-project.properties +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/__init__.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/fake_robotd.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/fixtures/duck_ipc_proto.json +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/live/__init__.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/live/test_live_cli.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_addressing.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_check_tutorial.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_cli.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_cli_introspection.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_client.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_default_rules.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_duck.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_engine.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_env.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_env_doctor.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_fake_robotd.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_gate.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_hosts.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_human_gate.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_idle.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_intents.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_lane.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_learn_skill.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_links.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_liveness.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_model.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_no_config_writes.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_no_hardware_paths.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_no_secrets_in_output.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_params.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_policy.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_proto.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_record.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_release.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_replay.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_rule_engine.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_rules.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_rules_cli.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_sense.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_senselog.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_sink.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_skills.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_stack.py +0 -0
- {microduck_cli-0.9.6 → microduck_cli-0.9.7}/tests/test_zero_deps.py +0 -0
|
@@ -191,6 +191,16 @@ tell motion from a static pose (this is how the "no gait" finding above was
|
|
|
191
191
|
made). If no graphical session exists, say so and use `--headless` plus
|
|
192
192
|
`duck monitor --json` instead of pretending to have looked.
|
|
193
193
|
|
|
194
|
+
**Record the whole session instead of one-off shots.** `microduck trace run
|
|
195
|
+
--plan <plan.toml>` (build one with `trace plan --from-tutorial <mdx>`, or hand
|
|
196
|
+
write it) replays a sequence of commands and traces each one — command, rc,
|
|
197
|
+
daemon log lines, and a viewer frame wherever the plan asks for a `shot` — into
|
|
198
|
+
one run directory. For a single command, `microduck trace exec -- <cmd>` traces
|
|
199
|
+
just that. Either way, `microduck trace render <run-dir>` (or `trace serve
|
|
200
|
+
<run-dir>` to open it in a browser immediately) turns the run into the same
|
|
201
|
+
MicroDuck Run Trace page every time — the committed example is
|
|
202
|
+
`docs/traces/2026-09-08-spark-tutorial/`.
|
|
203
|
+
|
|
194
204
|
## Close the simulation
|
|
195
205
|
|
|
196
206
|
```bash
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
run-trace-tool
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
run-trace-tool
|
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "run-trace-tool",
|
|
3
|
+
"title": "run-trace tool",
|
|
4
|
+
"schema_version": 6,
|
|
5
|
+
"status": "exported",
|
|
6
|
+
"created": "2026-09-08T14:50:13Z",
|
|
7
|
+
"updated": "2026-09-08T14:59:25Z",
|
|
8
|
+
"claims": [
|
|
9
|
+
{
|
|
10
|
+
"id": "c1",
|
|
11
|
+
"kind": "announcement",
|
|
12
|
+
"text": "microduck-cli ships a run-trace tool: one command re-runs the tutorial's steps, traces every command, daemon log line and viewer frame with wall-clock stamps, and regenerates the same MicroDuck Run Trace page verbatim \u2014 as a standalone local HTML file and as a Claude artifact fragment",
|
|
13
|
+
"origin": "user",
|
|
14
|
+
"status": "confirmed",
|
|
15
|
+
"honesty_conditions": [
|
|
16
|
+
{
|
|
17
|
+
"id": "h8",
|
|
18
|
+
"text": "a windowed trace run on Spark and a render of the committed example both work from a clean checkout of the PR branch",
|
|
19
|
+
"status": "confirmed",
|
|
20
|
+
"instruction": ""
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"hard_questions": [],
|
|
24
|
+
"links": [],
|
|
25
|
+
"instruction": "verify with the success signal: import + render the committed example byte-for-byte, then one fresh windowed run",
|
|
26
|
+
"revisions": []
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "c2",
|
|
30
|
+
"kind": "requirement",
|
|
31
|
+
"text": "the tool lives in docs/tools/ beside check_tutorial.py as trace_run.py (the tracer that runs steps and writes events.jsonl + shots) and trace_page.py (the generator that turns a run directory into the page) \u2014 repo tooling, not part of the wheel; tests/test_check_tutorial.py already shows the load-by-path test pattern",
|
|
32
|
+
"origin": "llm",
|
|
33
|
+
"status": "rejected",
|
|
34
|
+
"honesty_conditions": [],
|
|
35
|
+
"hard_questions": [],
|
|
36
|
+
"links": [],
|
|
37
|
+
"instruction": "",
|
|
38
|
+
"revisions": []
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "c3",
|
|
42
|
+
"kind": "boundary",
|
|
43
|
+
"text": "no new CLI noun or verb: adding microduck trace would pull the catalog, overview, learn and rubric contracts (three-places-in-lockstep in CLAUDE.md) and any image dependency into a wheel that must stay dependencies = []",
|
|
44
|
+
"origin": "llm",
|
|
45
|
+
"status": "rejected",
|
|
46
|
+
"honesty_conditions": [],
|
|
47
|
+
"hard_questions": [],
|
|
48
|
+
"links": [],
|
|
49
|
+
"instruction": "",
|
|
50
|
+
"revisions": []
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"id": "c4",
|
|
54
|
+
"kind": "requirement",
|
|
55
|
+
"text": "the step plan is data, not code: the tracer reads the tutorial's fenced bash commands (check_tutorial.py's extract_commands, which already skips nocheck fences) plus a small sidecar (TOML) that says where to sleep, screenshot, retry once, or gate \u2014 so the same tutorial file regenerates the same run",
|
|
56
|
+
"origin": "llm",
|
|
57
|
+
"status": "confirmed",
|
|
58
|
+
"honesty_conditions": [
|
|
59
|
+
{
|
|
60
|
+
"id": "h9",
|
|
61
|
+
"text": "trace plan --from-tutorial produces the same command list check_tutorial.py extracts (26 lines for the current tutorial), nocheck fences skipped",
|
|
62
|
+
"status": "confirmed",
|
|
63
|
+
"instruction": ""
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"hard_questions": [],
|
|
67
|
+
"links": [],
|
|
68
|
+
"instruction": "share the extraction rules: move the fenced-block extractor into microduck_cli/trace/plan.py and have docs/tools/check_tutorial.py keep its own copy untouched (docs script, not a package importer); a test compares both on the tutorial fixture",
|
|
69
|
+
"revisions": []
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"id": "c5",
|
|
73
|
+
"kind": "requirement",
|
|
74
|
+
"text": "two outputs from one generator: index.html (a complete document, opens from file:// or python3 -m http.server, all data and frames inlined as data URIs, fonts falling back to system stacks offline) and trace.html (the same body as an Artifact fragment without doctype/head/body, which the Artifact tool wraps)",
|
|
75
|
+
"origin": "llm",
|
|
76
|
+
"status": "confirmed",
|
|
77
|
+
"honesty_conditions": [
|
|
78
|
+
{
|
|
79
|
+
"id": "h10",
|
|
80
|
+
"text": "index.html opens from file:// with no network and shows the frames; trace.html has no doctype/html/head/body and starts with <title>",
|
|
81
|
+
"status": "confirmed",
|
|
82
|
+
"instruction": ""
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
"hard_questions": [],
|
|
86
|
+
"links": [],
|
|
87
|
+
"instruction": "render writes trace.html (fragment) then index.html = skeleton + fragment; test both properties",
|
|
88
|
+
"revisions": []
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"id": "c6",
|
|
92
|
+
"kind": "requirement",
|
|
93
|
+
"text": "screenshots without Pillow: capture the window only with gnome-screenshot -w (the tutorial's own recipe) after focusing the MuJoCo window, or capture full-screen and record the xwininfo geometry so the page crops with CSS object-position \u2014 no image library in the repo; today's rt.py used PIL, which is neither a dev dep nor in uv.lock",
|
|
94
|
+
"origin": "llm",
|
|
95
|
+
"status": "confirmed",
|
|
96
|
+
"honesty_conditions": [
|
|
97
|
+
{
|
|
98
|
+
"id": "h11",
|
|
99
|
+
"text": "no import of PIL anywhere under microduck_cli; a frame captured window-only is the MuJoCo window and nothing else",
|
|
100
|
+
"status": "confirmed",
|
|
101
|
+
"instruction": ""
|
|
102
|
+
}
|
|
103
|
+
],
|
|
104
|
+
"hard_questions": [],
|
|
105
|
+
"links": [],
|
|
106
|
+
"instruction": "capture.py: focus the 'MuJoCo : scene' window if a focus tool exists, gnome-screenshot -w; else full-screen + geometry from xwininfo recorded on the shot event, and the page crops with object-position/object-fit from that geometry",
|
|
107
|
+
"revisions": []
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"id": "c7",
|
|
111
|
+
"kind": "requirement",
|
|
112
|
+
"text": "CI lint covers the tool: the lint job's black/isort/flake8 paths add docs/tools (they list only microduck_cli tests today), tests load both scripts by path, and a fixture events.jsonl + two tiny JPEGs regenerate a page in a test that asserts the title, the inlined data and the frame count",
|
|
113
|
+
"origin": "llm",
|
|
114
|
+
"status": "rejected",
|
|
115
|
+
"honesty_conditions": [],
|
|
116
|
+
"hard_questions": [],
|
|
117
|
+
"links": [],
|
|
118
|
+
"instruction": "",
|
|
119
|
+
"revisions": []
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"id": "c8",
|
|
123
|
+
"kind": "boundary",
|
|
124
|
+
"text": "the page never smooths a run: a failed attempt stays on the timeline in red beside its retry, a headless run shows the frame panel empty with the reason, interpolated positions (trainer iterations) are labelled as interpolated \u2014 the honesty rules of the verification records apply to the picture",
|
|
125
|
+
"origin": "llm",
|
|
126
|
+
"status": "confirmed",
|
|
127
|
+
"honesty_conditions": [
|
|
128
|
+
{
|
|
129
|
+
"id": "h12",
|
|
130
|
+
"text": "a run with a failed then retried command renders both spans, the failed one in the failure colour; a headless run renders the frame panel with the reason text",
|
|
131
|
+
"status": "confirmed",
|
|
132
|
+
"instruction": ""
|
|
133
|
+
}
|
|
134
|
+
],
|
|
135
|
+
"hard_questions": [],
|
|
136
|
+
"links": [],
|
|
137
|
+
"instruction": "fixture events with rc=2 then rc=0 for the same label; assert both spans and the frame-panel text in the rendered HTML",
|
|
138
|
+
"revisions": []
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"id": "c9",
|
|
142
|
+
"kind": "requirement",
|
|
143
|
+
"text": "run output lives outside the tree: default --out .local/trace/<UTC-stamp>/ (untracked; .local is already excluded by the markdownlint glob), holding events.jsonl, steps/*.out|.err, shots/, index.html, trace.html \u2014 nothing generated is committed except a checked-in sample page under docs/tools/ if the user wants one",
|
|
144
|
+
"origin": "llm",
|
|
145
|
+
"status": "rejected",
|
|
146
|
+
"honesty_conditions": [],
|
|
147
|
+
"hard_questions": [],
|
|
148
|
+
"links": [],
|
|
149
|
+
"instruction": "",
|
|
150
|
+
"revisions": []
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"id": "c10",
|
|
154
|
+
"kind": "non_goal",
|
|
155
|
+
"text": "not a generic tracer: the tier map (microduck-cli / robotd / microduck_rl, operator, viewer, GPU) and its edges are MicroDuck-specific and hard-coded in the generator; reachy-mini-cli or neurosymbolic-system would cite the method, not import the map",
|
|
156
|
+
"origin": "llm",
|
|
157
|
+
"status": "confirmed",
|
|
158
|
+
"honesty_conditions": [],
|
|
159
|
+
"hard_questions": [],
|
|
160
|
+
"links": [],
|
|
161
|
+
"instruction": "",
|
|
162
|
+
"revisions": []
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"id": "c11",
|
|
166
|
+
"kind": "requirement",
|
|
167
|
+
"text": "every PR bumps the version and prepends a CHANGELOG entry (version-check job); this one is a patch bump with docs/tools, tests, CI and CLAUDE.md/README pointers",
|
|
168
|
+
"origin": "llm",
|
|
169
|
+
"status": "confirmed",
|
|
170
|
+
"honesty_conditions": [
|
|
171
|
+
{
|
|
172
|
+
"id": "h13",
|
|
173
|
+
"text": "pyproject version differs from origin/main and CHANGELOG has the entry",
|
|
174
|
+
"status": "confirmed",
|
|
175
|
+
"instruction": ""
|
|
176
|
+
}
|
|
177
|
+
],
|
|
178
|
+
"hard_questions": [],
|
|
179
|
+
"links": [],
|
|
180
|
+
"instruction": "run the version-bump skill (patch) as the last step before cicd open",
|
|
181
|
+
"revisions": []
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"id": "c12",
|
|
185
|
+
"kind": "assumption",
|
|
186
|
+
"text": "the runner is Linux/GNOME-shaped: gnome-screenshot, xwininfo, loginctl and the session DISPLAY/XAUTHORITY/DBUS address are discovered from the gnome-shell process environment as the operate-microduck skill prescribes; with no graphical session it runs the tutorial headless and skips frames",
|
|
187
|
+
"origin": "llm",
|
|
188
|
+
"status": "confirmed",
|
|
189
|
+
"honesty_conditions": [],
|
|
190
|
+
"hard_questions": [],
|
|
191
|
+
"links": [],
|
|
192
|
+
"instruction": "",
|
|
193
|
+
"revisions": []
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"id": "c13",
|
|
197
|
+
"kind": "decision",
|
|
198
|
+
"text": "USER DECISION: trace is a CLI noun, microduck trace, with its own overview (rubric) \u2014 not a docs/tools script; it is relevant to operators and agents, not only to the tutorial",
|
|
199
|
+
"origin": "llm",
|
|
200
|
+
"status": "confirmed",
|
|
201
|
+
"honesty_conditions": [],
|
|
202
|
+
"hard_questions": [],
|
|
203
|
+
"links": [],
|
|
204
|
+
"instruction": "",
|
|
205
|
+
"revisions": []
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"id": "c14",
|
|
209
|
+
"kind": "decision",
|
|
210
|
+
"text": "USER DECISION: a trace covers ANY CLI work \u2014 a tutorial run, the post-run checks, an exploratory session, or an import of an existing run directory \u2014 not only tutorial steps 1-11",
|
|
211
|
+
"origin": "llm",
|
|
212
|
+
"status": "confirmed",
|
|
213
|
+
"honesty_conditions": [],
|
|
214
|
+
"hard_questions": [],
|
|
215
|
+
"links": [],
|
|
216
|
+
"instruction": "",
|
|
217
|
+
"revisions": []
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"id": "c15",
|
|
221
|
+
"kind": "decision",
|
|
222
|
+
"text": "USER DECISION: pausing the desktop auto-lock for a windowed run is opt-in (a flag), restored afterwards; without the flag the tool warns when lock is armed and proceeds",
|
|
223
|
+
"origin": "llm",
|
|
224
|
+
"status": "confirmed",
|
|
225
|
+
"honesty_conditions": [],
|
|
226
|
+
"hard_questions": [],
|
|
227
|
+
"links": [],
|
|
228
|
+
"instruction": "",
|
|
229
|
+
"revisions": []
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"id": "c16",
|
|
233
|
+
"kind": "decision",
|
|
234
|
+
"text": "USER DECISION: the PR ships the generator and today's page as a committed example; publishing to a Claude artifact stays an agent step on the fragment",
|
|
235
|
+
"origin": "llm",
|
|
236
|
+
"status": "confirmed",
|
|
237
|
+
"honesty_conditions": [],
|
|
238
|
+
"hard_questions": [],
|
|
239
|
+
"links": [],
|
|
240
|
+
"instruction": "",
|
|
241
|
+
"revisions": []
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"id": "c17",
|
|
245
|
+
"kind": "requirement",
|
|
246
|
+
"text": "engine logic lives in microduck_cli/trace/ (events.py schema + recorder, plan.py, capture.py for frames, render.py for the page, serve.py) and cli/_commands/trace.py is thin argparse wiring for a noun group built with parser_class=type(p) so nested parse errors keep the CliError contract; the noun gets overview, catalog entries, the _VERBS list and learn's _TEXT/_as_json_payload in lockstep",
|
|
247
|
+
"origin": "llm",
|
|
248
|
+
"status": "confirmed",
|
|
249
|
+
"honesty_conditions": [
|
|
250
|
+
{
|
|
251
|
+
"id": "h1",
|
|
252
|
+
"text": "nothing under microduck_cli/trace/ imports cli/ except cli/_errors, and _commands/trace.py contains no engine logic (the reachy split)",
|
|
253
|
+
"status": "confirmed",
|
|
254
|
+
"instruction": ""
|
|
255
|
+
}
|
|
256
|
+
],
|
|
257
|
+
"hard_questions": [],
|
|
258
|
+
"links": [],
|
|
259
|
+
"instruction": "mirror cli/_commands/cli.py for the noun group and the behavior/ package split for the engine; add catalog entries for (trace,) and each verb, the _VERBS row, and learn's text + JSON payload",
|
|
260
|
+
"revisions": []
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
"id": "c18",
|
|
264
|
+
"kind": "requirement",
|
|
265
|
+
"text": "verbs: trace overview; trace run --plan <toml> (execute a step plan, tracing each command's argv, exit, timing, stdout first line, timestamped stderr lines, the robotd/body log tails and viewer frames); trace exec -- <command> (trace one arbitrary command into the current run dir, so exploratory or post-run work is traced the same way); trace plan --from-tutorial <mdx> (derive a plan from the fenced bash commands, nocheck fences skipped, with an editable sidecar for sleeps/frames/retries); trace import <dir> (adopt an events.jsonl + shots directory produced elsewhere, e.g. today's scratch tracer); trace render <run-dir> (write index.html and trace.html); trace serve <run-dir> (stdlib http.server on the run dir); trace status/list of run dirs",
|
|
266
|
+
"origin": "llm",
|
|
267
|
+
"status": "confirmed",
|
|
268
|
+
"honesty_conditions": [
|
|
269
|
+
{
|
|
270
|
+
"id": "h2",
|
|
271
|
+
"text": "every verb has --json, raises CliError on failure, and trace overview exits 0 on any argument (rubric)",
|
|
272
|
+
"status": "confirmed",
|
|
273
|
+
"instruction": ""
|
|
274
|
+
}
|
|
275
|
+
],
|
|
276
|
+
"hard_questions": [],
|
|
277
|
+
"links": [],
|
|
278
|
+
"instruction": "one register(sub) per verb inside _commands/trace.py; run/exec share a Recorder; serve wraps http.server.ThreadingHTTPServer bound to 127.0.0.1 with a printed URL",
|
|
279
|
+
"revisions": []
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"id": "c19",
|
|
283
|
+
"kind": "requirement",
|
|
284
|
+
"text": "one event schema (t, wall, lane, kind, label, step, and per-kind fields) shared by run, exec and import \u2014 the renderer never knows which mode produced a record; kinds: cmd-start, cmd-end, stderr, log, shot, note",
|
|
285
|
+
"origin": "llm",
|
|
286
|
+
"status": "confirmed",
|
|
287
|
+
"honesty_conditions": [
|
|
288
|
+
{
|
|
289
|
+
"id": "h3",
|
|
290
|
+
"text": "trace render accepts a run dir produced by run, exec or import without a mode flag",
|
|
291
|
+
"status": "confirmed",
|
|
292
|
+
"instruction": ""
|
|
293
|
+
}
|
|
294
|
+
],
|
|
295
|
+
"hard_questions": [],
|
|
296
|
+
"links": [],
|
|
297
|
+
"instruction": "events.py defines the record dataclasses and a load()/append() pair used by run, exec, import and render; import validates each line and reports the first bad one as CliError",
|
|
298
|
+
"revisions": []
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
"id": "c20",
|
|
302
|
+
"kind": "requirement",
|
|
303
|
+
"text": "the run directory defaults to <DUCK_SIM_STATE>/trace/<UTC-stamp>/ (--out overrides): events.jsonl, steps/NN-name.out|.err, shots/, plan.toml, index.html, trace.html; the same run dir renders byte-for-byte identical pages on every render (verbatim regeneration is a test)",
|
|
304
|
+
"origin": "llm",
|
|
305
|
+
"status": "confirmed",
|
|
306
|
+
"honesty_conditions": [
|
|
307
|
+
{
|
|
308
|
+
"id": "h4",
|
|
309
|
+
"text": "rendering the same run dir twice yields identical bytes \u2014 no wall-clock, random id or dict-order nondeterminism in render",
|
|
310
|
+
"status": "confirmed",
|
|
311
|
+
"instruction": ""
|
|
312
|
+
}
|
|
313
|
+
],
|
|
314
|
+
"hard_questions": [],
|
|
315
|
+
"links": [],
|
|
316
|
+
"instruction": "render sorts everything it emits, embeds frames in filename order, and takes no clock; test renders twice and compares bytes",
|
|
317
|
+
"revisions": []
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
"id": "c21",
|
|
321
|
+
"kind": "requirement",
|
|
322
|
+
"text": "today's run is the committed example: docs/traces/2026-09-08-spark-tutorial/ holds events.jsonl, the 12 frames and the rendered index.html + trace.html, imported through trace import and re-rendered by trace render; a test renders the example dir and diffs against the committed page",
|
|
323
|
+
"origin": "llm",
|
|
324
|
+
"status": "confirmed",
|
|
325
|
+
"honesty_conditions": [
|
|
326
|
+
{
|
|
327
|
+
"id": "h5",
|
|
328
|
+
"text": "the committed example is imported from today's scratch events.jsonl unchanged except home-path redaction, and its page differs from the artifact only where the generator's template changed",
|
|
329
|
+
"status": "confirmed",
|
|
330
|
+
"instruction": ""
|
|
331
|
+
}
|
|
332
|
+
],
|
|
333
|
+
"hard_questions": [],
|
|
334
|
+
"links": [],
|
|
335
|
+
"instruction": "copy the scratch run's events.jsonl and 12 web JPEGs to docs/traces/2026-09-08-spark-tutorial/, redact /home/<user> to ~, render, commit index.html + trace.html; the test re-renders and diffs",
|
|
336
|
+
"revisions": []
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
"id": "c22",
|
|
340
|
+
"kind": "boundary",
|
|
341
|
+
"text": "the trace noun adds no runtime dependency: stdlib only (json, subprocess, base64, http.server, threading); no Pillow \u2014 frames are captured window-only (gnome-screenshot -w after focusing the MuJoCo window via xdotool/wmctrl if present, else full-screen with recorded xwininfo geometry that the page crops with CSS); dependencies = [] is unchanged",
|
|
342
|
+
"origin": "llm",
|
|
343
|
+
"status": "confirmed",
|
|
344
|
+
"honesty_conditions": [
|
|
345
|
+
{
|
|
346
|
+
"id": "h7",
|
|
347
|
+
"text": "uv run python -c 'import microduck_cli.trace' works in a venv with no extras and pyproject dependencies is still []",
|
|
348
|
+
"status": "confirmed",
|
|
349
|
+
"instruction": ""
|
|
350
|
+
}
|
|
351
|
+
],
|
|
352
|
+
"hard_questions": [],
|
|
353
|
+
"links": [],
|
|
354
|
+
"instruction": "grep test: no third-party import under microduck_cli/trace; pyproject dependencies stays []",
|
|
355
|
+
"revisions": []
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
"id": "c23",
|
|
359
|
+
"kind": "requirement",
|
|
360
|
+
"text": "trace run and exec honour the repo's gate: commands that move hardware are passed through as typed (--apply must be in the plan); the tracer never injects --apply, never answers a TTY prompt, and a dry-run plan line is recorded as what it is",
|
|
361
|
+
"origin": "llm",
|
|
362
|
+
"status": "confirmed",
|
|
363
|
+
"honesty_conditions": [
|
|
364
|
+
{
|
|
365
|
+
"id": "h6",
|
|
366
|
+
"text": "a plan line without --apply on a pipe records a dry-run plan and moves nothing \u2014 the tracer is not a way around the gate",
|
|
367
|
+
"status": "confirmed",
|
|
368
|
+
"instruction": ""
|
|
369
|
+
}
|
|
370
|
+
],
|
|
371
|
+
"hard_questions": [],
|
|
372
|
+
"links": [],
|
|
373
|
+
"instruction": "the plan's command strings are executed verbatim through bash -c with stdin from /dev/null; document that --apply belongs in the plan",
|
|
374
|
+
"revisions": []
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
"id": "c24",
|
|
378
|
+
"kind": "audience",
|
|
379
|
+
"text": "operators and agents driving the duck who want a shareable, honest replay of a session \u2014 the tutorial's authors and reviewers first, then anyone reporting a run",
|
|
380
|
+
"origin": "llm",
|
|
381
|
+
"status": "confirmed",
|
|
382
|
+
"honesty_conditions": [
|
|
383
|
+
{
|
|
384
|
+
"id": "h14",
|
|
385
|
+
"text": "trace overview names operators, agents and tutorial reviewers as the audience",
|
|
386
|
+
"status": "confirmed",
|
|
387
|
+
"instruction": ""
|
|
388
|
+
}
|
|
389
|
+
],
|
|
390
|
+
"hard_questions": [],
|
|
391
|
+
"links": [],
|
|
392
|
+
"instruction": "the overview and catalog text name this audience first",
|
|
393
|
+
"revisions": []
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
"id": "c25",
|
|
397
|
+
"kind": "after_state",
|
|
398
|
+
"text": "microduck trace run --plan tutorial.toml (or exec/import) produces a run directory that trace render turns into the MicroDuck Run Trace page: the three-tier map lighting up over a scrubbable timeline with the viewer frames, openable from file://, served with trace serve, or published as an artifact from trace.html \u2014 and rendering the same run dir twice gives identical bytes",
|
|
399
|
+
"origin": "llm",
|
|
400
|
+
"status": "confirmed",
|
|
401
|
+
"honesty_conditions": [
|
|
402
|
+
{
|
|
403
|
+
"id": "h15",
|
|
404
|
+
"text": "the after-state walk-through in the PR description was executed and its commands appear in the PR",
|
|
405
|
+
"status": "confirmed",
|
|
406
|
+
"instruction": ""
|
|
407
|
+
}
|
|
408
|
+
],
|
|
409
|
+
"hard_questions": [],
|
|
410
|
+
"links": [],
|
|
411
|
+
"instruction": "this is the acceptance walk-through in the PR description",
|
|
412
|
+
"revisions": []
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
"id": "c26",
|
|
416
|
+
"kind": "before_state",
|
|
417
|
+
"text": "today the trace exists once, hand-built: a scratch rt.py in a session scratchpad, a hand-written page.html, PIL cropping, and manual bash chains \u2014 nobody can regenerate it, and the tier map's honesty rules live only in the page's prose",
|
|
418
|
+
"origin": "llm",
|
|
419
|
+
"status": "confirmed",
|
|
420
|
+
"honesty_conditions": [
|
|
421
|
+
{
|
|
422
|
+
"id": "h16",
|
|
423
|
+
"text": "the scratch rt.py and page.html are not copied into the repo; their content is re-expressed inside microduck_cli/trace",
|
|
424
|
+
"status": "confirmed",
|
|
425
|
+
"instruction": ""
|
|
426
|
+
}
|
|
427
|
+
],
|
|
428
|
+
"hard_questions": [],
|
|
429
|
+
"links": [],
|
|
430
|
+
"instruction": "the CHANGELOG entry says what replaced the scratch tracer",
|
|
431
|
+
"revisions": []
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
"id": "c27",
|
|
435
|
+
"kind": "why_it_matters",
|
|
436
|
+
"text": "a verification record says what happened; the trace shows which tier did it and when, from the same timestamps \u2014 a reviewer of the tutorial or of a failed run can see the first env up die and the retry succeed instead of reading two log excerpts",
|
|
437
|
+
"origin": "llm",
|
|
438
|
+
"status": "confirmed",
|
|
439
|
+
"honesty_conditions": [
|
|
440
|
+
{
|
|
441
|
+
"id": "h17",
|
|
442
|
+
"text": "the committed example page shows the 2026-09-08 first env up failure and its retry side by side",
|
|
443
|
+
"status": "confirmed",
|
|
444
|
+
"instruction": ""
|
|
445
|
+
}
|
|
446
|
+
],
|
|
447
|
+
"hard_questions": [],
|
|
448
|
+
"links": [],
|
|
449
|
+
"instruction": "the trace overview text carries this one-liner",
|
|
450
|
+
"revisions": []
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
"id": "c28",
|
|
454
|
+
"kind": "success_signal",
|
|
455
|
+
"text": "from a clean checkout: microduck trace import docs/traces/2026-09-08-spark-tutorial && microduck trace render <dir> reproduces the committed index.html byte-for-byte (a pytest asserts it); teken cli doctor --strict passes with the new noun; test_every_catalog_path_resolves covers trace; a fresh windowed trace run --plan on Spark produces a page a reviewer can scrub through",
|
|
456
|
+
"origin": "llm",
|
|
457
|
+
"status": "confirmed",
|
|
458
|
+
"honesty_conditions": [
|
|
459
|
+
{
|
|
460
|
+
"id": "h18",
|
|
461
|
+
"text": "every clause of the success signal maps to a named test or a command recorded in the PR body",
|
|
462
|
+
"status": "confirmed",
|
|
463
|
+
"instruction": ""
|
|
464
|
+
}
|
|
465
|
+
],
|
|
466
|
+
"hard_questions": [],
|
|
467
|
+
"links": [],
|
|
468
|
+
"instruction": "each clause is a test or a recorded command in the PR",
|
|
469
|
+
"revisions": []
|
|
470
|
+
}
|
|
471
|
+
],
|
|
472
|
+
"open_vagueness": [
|
|
473
|
+
{
|
|
474
|
+
"id": "v1",
|
|
475
|
+
"text": "the first env up --sim failure on 2026-09-08 (body exited silently) is unexplained; a tracer that retries once will keep hitting it and the page will keep showing it \u2014 root cause is outside this tool",
|
|
476
|
+
"kind": "unknown_nonblocking",
|
|
477
|
+
"claim_id": null,
|
|
478
|
+
"resolved": false,
|
|
479
|
+
"resolution": "",
|
|
480
|
+
"resolution_claim_id": null
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
"id": "v2",
|
|
484
|
+
"text": "whether the generated page should be a committed sample (docs/tools/sample-trace/index.html, ~600 KB with frames) or only regenerated on demand \u2014 repo weight vs a browsable example",
|
|
485
|
+
"kind": "unknown_nonblocking",
|
|
486
|
+
"claim_id": null,
|
|
487
|
+
"resolved": false,
|
|
488
|
+
"resolution": "",
|
|
489
|
+
"resolution_claim_id": null
|
|
490
|
+
}
|
|
491
|
+
],
|
|
492
|
+
"scope_entries": [
|
|
493
|
+
{
|
|
494
|
+
"id": "s1",
|
|
495
|
+
"surface": "docs/tools/check_tutorial.py + tests/test_check_tutorial.py",
|
|
496
|
+
"finding": "docs/tools/ is the established home for repo-side tooling that is not shipped in the wheel; its tests import the script by path via importlib, which the new tool's tests can copy",
|
|
497
|
+
"seeds": [
|
|
498
|
+
"c2"
|
|
499
|
+
]
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
"id": "s2",
|
|
503
|
+
"surface": "microduck_cli/cli (three-places rule, teken rubric) + pyproject dependencies = []",
|
|
504
|
+
"finding": "a CLI verb would cost the catalog/overview/learn lockstep and the rubric gate for a docs-time tool, and the wheel must stay zero-dep; the tool stays outside the package",
|
|
505
|
+
"seeds": [
|
|
506
|
+
"c3"
|
|
507
|
+
]
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
"id": "s3",
|
|
511
|
+
"surface": "docs/tools/check_tutorial.py extract_commands / _iter_fenced_blocks",
|
|
512
|
+
"finding": "the tutorial's command list is already extractable from the mdx with nocheck fences skipped; the tracer can reuse it instead of hand-listing steps, keeping the tutorial the single source of the run",
|
|
513
|
+
"seeds": [
|
|
514
|
+
"c4"
|
|
515
|
+
]
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
"id": "s4",
|
|
519
|
+
"surface": "Artifact tool contract (wraps a fragment; forbids doctype/html/head/body) vs a local static site",
|
|
520
|
+
"finding": "one body serves both targets; only the outer skeleton differs, so the generator emits the fragment and a wrapped copy rather than two page sources",
|
|
521
|
+
"seeds": [
|
|
522
|
+
"c5"
|
|
523
|
+
]
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
"id": "s5",
|
|
527
|
+
"surface": "pyproject [dependency-groups].dev + uv.lock (no pillow) + .claude/skills/operate-microduck (screenshot recipe)",
|
|
528
|
+
"finding": "the scratch tracer's PIL crop cannot land as-is; the dev group has no image library and the operator skill already prescribes gnome-screenshot -w for a window-only capture",
|
|
529
|
+
"seeds": [
|
|
530
|
+
"c6"
|
|
531
|
+
]
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
"id": "s6",
|
|
535
|
+
"surface": ".github/workflows/tests.yml lint job + [tool.coverage.run] source",
|
|
536
|
+
"finding": "CI lints microduck_cli and tests only, so docs/tools would drift unlinted unless the paths are added; coverage is scoped to the package, so the tool's tests do not move the gate",
|
|
537
|
+
"seeds": [
|
|
538
|
+
"c7"
|
|
539
|
+
]
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
"id": "s7",
|
|
543
|
+
"surface": "docs/verification/2026-09-07-spark-retest.md + 2026-09-08 record (honest-failure convention)",
|
|
544
|
+
"finding": "records keep first attempts and failures verbatim; the generated page must keep the same discipline or it contradicts the record it illustrates",
|
|
545
|
+
"seeds": [
|
|
546
|
+
"c8"
|
|
547
|
+
]
|
|
548
|
+
},
|
|
549
|
+
{
|
|
550
|
+
"id": "s8",
|
|
551
|
+
"surface": ".gitignore + markdownlint globs (#.local)",
|
|
552
|
+
"finding": ".local is already the convention for untracked local artefacts in this repo's lint config, so run directories belong there and stay out of PRs",
|
|
553
|
+
"seeds": [
|
|
554
|
+
"c9"
|
|
555
|
+
]
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
"id": "s9",
|
|
559
|
+
"surface": "CLAUDE.md sibling-repos section (cite-don't-import, extraction seams)",
|
|
560
|
+
"finding": "a generic trace library is the neurosymbolic-system extraction question again; keep the map duck-specific now and let a sibling cite the pattern",
|
|
561
|
+
"seeds": [
|
|
562
|
+
"c10"
|
|
563
|
+
]
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
"id": "s10",
|
|
567
|
+
"surface": "CHANGELOG.md + tests.yml version-check",
|
|
568
|
+
"finding": "docs/tooling-only PRs still need the bump; the entry documents the tool and the two output files",
|
|
569
|
+
"seeds": [
|
|
570
|
+
"c11"
|
|
571
|
+
]
|
|
572
|
+
},
|
|
573
|
+
{
|
|
574
|
+
"id": "s11",
|
|
575
|
+
"surface": ".claude/skills/operate-microduck/SKILL.md (Watch it section) + Spark/Thor/Orin display state",
|
|
576
|
+
"finding": "the display-owner discovery recipe is already written down; the tracer automates it and degrades to headless rather than failing",
|
|
577
|
+
"seeds": [
|
|
578
|
+
"c12"
|
|
579
|
+
]
|
|
580
|
+
}
|
|
581
|
+
],
|
|
582
|
+
"lapses": [],
|
|
583
|
+
"obligations": []
|
|
584
|
+
}
|