dsh-compound-engineering 0.0.0-stage → 0.1.0
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.
- package/LICENSE +21 -0
- package/README.md +160 -2
- package/README.zh.md +161 -0
- package/cordis.patch.yml +6 -0
- package/lib/frontmatter.js +167 -0
- package/lib/index.js +46 -0
- package/lib/provider.js +201 -0
- package/package.json +62 -4
- package/skills/CODING_STANDARDS.md +68 -0
- package/skills/ce-babysit-pr/SKILL.md +59 -0
- package/skills/ce-babysit-pr/references/branch-currency.md +22 -0
- package/skills/ce-babysit-pr/references/envelope.md +44 -0
- package/skills/ce-babysit-pr/references/pipeline.md +15 -0
- package/skills/ce-babysit-pr/references/report.md +20 -0
- package/skills/ce-babysit-pr/references/settle.md +37 -0
- package/skills/ce-babysit-pr/references/setup.md +33 -0
- package/skills/ce-babysit-pr/references/stack-commands.md +39 -0
- package/skills/ce-babysit-pr/references/stack.md +43 -0
- package/skills/ce-babysit-pr/references/tick.md +102 -0
- package/skills/ce-babysit-pr/references/watch-loop.md +222 -0
- package/skills/ce-babysit-pr/scripts/pr-snapshot +3656 -0
- package/skills/ce-bakeoff/SKILL.md +48 -0
- package/skills/ce-bakeoff/references/candidates.md +37 -0
- package/skills/ce-bakeoff/references/judging.md +19 -0
- package/skills/ce-bakeoff/references/output.md +11 -0
- package/skills/ce-bakeoff/references/verification.md +15 -0
- package/skills/ce-brainstorm/SKILL.md +69 -0
- package/skills/ce-brainstorm/references/agents/slack-researcher.md +127 -0
- package/skills/ce-brainstorm/references/approaches.md +57 -0
- package/skills/ce-brainstorm/references/bakeoff.md +9 -0
- package/skills/ce-brainstorm/references/blindspot-pass.md +70 -0
- package/skills/ce-brainstorm/references/brainstorm-sections.md +458 -0
- package/skills/ce-brainstorm/references/dialogue.md +89 -0
- package/skills/ce-brainstorm/references/handoff.md +187 -0
- package/skills/ce-brainstorm/references/html-rendering.md +638 -0
- package/skills/ce-brainstorm/references/interaction-rules.md +33 -0
- package/skills/ce-brainstorm/references/markdown-rendering.md +242 -0
- package/skills/ce-brainstorm/references/model-tiers.md +13 -0
- package/skills/ce-brainstorm/references/output-mode.md +26 -0
- package/skills/ce-brainstorm/references/phase-0.md +104 -0
- package/skills/ce-brainstorm/references/plan-write.md +32 -0
- package/skills/ce-brainstorm/references/product-pressure-test.md +42 -0
- package/skills/ce-brainstorm/references/reasoning-elevation.md +124 -0
- package/skills/ce-brainstorm/references/settled-decisions.md +45 -0
- package/skills/ce-brainstorm/references/synthesis-summary.md +149 -0
- package/skills/ce-brainstorm/references/universal-brainstorming.md +72 -0
- package/skills/ce-brainstorm/references/verdict-routing.md +26 -0
- package/skills/ce-brainstorm/references/visual-probes.md +164 -0
- package/skills/ce-brainstorm/scripts/elevation-dispatch.sh +288 -0
- package/skills/ce-brainstorm/scripts/light-webserver.js +1275 -0
- package/skills/ce-brainstorm/scripts/packs-resolve.py +737 -0
- package/skills/ce-brainstorm/scripts/peer-job-runner.py +2594 -0
- package/skills/ce-code-review/SKILL.md +40 -0
- package/skills/ce-code-review/references/action-class-rubric.md +67 -0
- package/skills/ce-code-review/references/cross-model-recovery.md +38 -0
- package/skills/ce-code-review/references/cross-model-review.md +191 -0
- package/skills/ce-code-review/references/depth-paths.md +32 -0
- package/skills/ce-code-review/references/diff-scope.md +59 -0
- package/skills/ce-code-review/references/dispatch-reviewers.md +135 -0
- package/skills/ce-code-review/references/findings-schema.json +125 -0
- package/skills/ce-code-review/references/finish-input.md +118 -0
- package/skills/ce-code-review/references/finish-review.md +202 -0
- package/skills/ce-code-review/references/intent-and-plan.md +73 -0
- package/skills/ce-code-review/references/modes-and-output.md +156 -0
- package/skills/ce-code-review/references/persona-catalog.md +66 -0
- package/skills/ce-code-review/references/personas/adversarial-reviewer.md +111 -0
- package/skills/ce-code-review/references/personas/agent-native-reviewer.md +173 -0
- package/skills/ce-code-review/references/personas/api-contract-reviewer.md +44 -0
- package/skills/ce-code-review/references/personas/correctness-reviewer.md +48 -0
- package/skills/ce-code-review/references/personas/data-migration-reviewer.md +111 -0
- package/skills/ce-code-review/references/personas/deployment-verification-agent.md +157 -0
- package/skills/ce-code-review/references/personas/julik-frontend-races-reviewer.md +45 -0
- package/skills/ce-code-review/references/personas/learnings-researcher.md +260 -0
- package/skills/ce-code-review/references/personas/maintainability-reviewer.md +85 -0
- package/skills/ce-code-review/references/personas/performance-reviewer.md +45 -0
- package/skills/ce-code-review/references/personas/previous-comments-reviewer.md +59 -0
- package/skills/ce-code-review/references/personas/project-standards-reviewer.md +77 -0
- package/skills/ce-code-review/references/personas/reliability-reviewer.md +49 -0
- package/skills/ce-code-review/references/personas/security-reviewer.md +50 -0
- package/skills/ce-code-review/references/personas/swift-ios-reviewer.md +99 -0
- package/skills/ce-code-review/references/personas/testing-reviewer.md +51 -0
- package/skills/ce-code-review/references/review-output-template.md +172 -0
- package/skills/ce-code-review/references/scope.md +176 -0
- package/skills/ce-code-review/references/select-and-route.md +93 -0
- package/skills/ce-code-review/references/subagent-template.md +206 -0
- package/skills/ce-code-review/references/validator-batch-template.md +67 -0
- package/skills/ce-code-review/scripts/cross-model-adversarial-review.sh +1275 -0
- package/skills/ce-code-review/scripts/findings-mechanics.py +274 -0
- package/skills/ce-code-review/scripts/packs-resolve.py +737 -0
- package/skills/ce-code-review/scripts/peer-job-runner.py +2594 -0
- package/skills/ce-code-review/scripts/review-scope.py +419 -0
- package/skills/ce-code-review/scripts/run-log.py +280 -0
- package/skills/ce-commit/SKILL.md +60 -0
- package/skills/ce-commit-push-pr/SKILL.md +69 -0
- package/skills/ce-commit-push-pr/references/apply-and-handoff.md +79 -0
- package/skills/ce-commit-push-pr/references/branch-creation.md +47 -0
- package/skills/ce-commit-push-pr/references/commit-and-push.md +26 -0
- package/skills/ce-commit-push-pr/references/compose.md +29 -0
- package/skills/ce-commit-push-pr/references/context.md +42 -0
- package/skills/ce-commit-push-pr/references/gh-stack-cli.md +83 -0
- package/skills/ce-commit-push-pr/references/pr-description-writing.md +208 -0
- package/skills/ce-commit-push-pr/references/stack-submit.md +81 -0
- package/skills/ce-compound/SKILL.md +79 -0
- package/skills/ce-compound/assets/resolution-template.md +96 -0
- package/skills/ce-compound/references/agents/best-practices-researcher.md +115 -0
- package/skills/ce-compound/references/agents/data-integrity-guardian.md +68 -0
- package/skills/ce-compound/references/agents/framework-docs-researcher.md +93 -0
- package/skills/ce-compound/references/agents/pattern-recognition-specialist.md +55 -0
- package/skills/ce-compound/references/agents/performance-oracle.md +108 -0
- package/skills/ce-compound/references/agents/security-sentinel.md +91 -0
- package/skills/ce-compound/references/agents/session-historian.md +82 -0
- package/skills/ce-compound/references/assembly.md +127 -0
- package/skills/ce-compound/references/concepts-vocabulary.md +98 -0
- package/skills/ce-compound/references/enhancement.md +42 -0
- package/skills/ce-compound/references/grounding-validation.md +89 -0
- package/skills/ce-compound/references/lightweight.md +56 -0
- package/skills/ce-compound/references/modes.md +13 -0
- package/skills/ce-compound/references/refresh-and-discoverability.md +96 -0
- package/skills/ce-compound/references/report.md +115 -0
- package/skills/ce-compound/references/research.md +144 -0
- package/skills/ce-compound/references/schema.yaml +236 -0
- package/skills/ce-compound/references/session-history.md +73 -0
- package/skills/ce-compound/references/yaml-schema.md +130 -0
- package/skills/ce-compound/scripts/packs-resolve.py +737 -0
- package/skills/ce-compound/scripts/session-history/__pycache__/dsh_session.cpython-314.pyc +0 -0
- package/skills/ce-compound/scripts/session-history/discover-sessions.sh +290 -0
- package/skills/ce-compound/scripts/session-history/discover_dsh.py +123 -0
- package/skills/ce-compound/scripts/session-history/dsh_session.py +225 -0
- package/skills/ce-compound/scripts/session-history/extract-errors.py +178 -0
- package/skills/ce-compound/scripts/session-history/extract-metadata.py +301 -0
- package/skills/ce-compound/scripts/session-history/extract-skeleton.py +346 -0
- package/skills/ce-compound/scripts/validate-doc-claims.py +497 -0
- package/skills/ce-compound/scripts/validate-frontmatter.py +137 -0
- package/skills/ce-compound-refresh/SKILL.md +88 -0
- package/skills/ce-compound-refresh/assets/resolution-template.md +96 -0
- package/skills/ce-compound-refresh/references/classify.md +42 -0
- package/skills/ce-compound-refresh/references/commit.md +7 -0
- package/skills/ce-compound-refresh/references/concepts-vocabulary.md +116 -0
- package/skills/ce-compound-refresh/references/discoverability.md +15 -0
- package/skills/ce-compound-refresh/references/investigate.md +23 -0
- package/skills/ce-compound-refresh/references/modes.md +27 -0
- package/skills/ce-compound-refresh/references/per-action-flows.md +142 -0
- package/skills/ce-compound-refresh/references/report.md +23 -0
- package/skills/ce-compound-refresh/references/schema.yaml +236 -0
- package/skills/ce-compound-refresh/references/scope.md +18 -0
- package/skills/ce-compound-refresh/references/worth-audit.md +35 -0
- package/skills/ce-compound-refresh/references/yaml-schema.md +130 -0
- package/skills/ce-compound-refresh/scripts/validate-doc-claims.py +497 -0
- package/skills/ce-compound-refresh/scripts/validate-frontmatter.py +137 -0
- package/skills/ce-debug/SKILL.md +122 -0
- package/skills/ce-debug/references/anti-patterns.md +91 -0
- package/skills/ce-debug/references/defense-in-depth.md +39 -0
- package/skills/ce-debug/references/fix.md +21 -0
- package/skills/ce-debug/references/investigate.md +114 -0
- package/skills/ce-debug/references/investigation-techniques.md +384 -0
- package/skills/ce-debug/references/pipeline-mode.md +78 -0
- package/skills/ce-debug/references/post-fix-handoff.md +60 -0
- package/skills/ce-debug/references/return-to-caller.md +57 -0
- package/skills/ce-doc-review/SKILL.md +75 -0
- package/skills/ce-doc-review/references/bulk-preview.md +146 -0
- package/skills/ce-doc-review/references/cross-model-review.md +207 -0
- package/skills/ce-doc-review/references/decision-primer.md +47 -0
- package/skills/ce-doc-review/references/dispatch.md +56 -0
- package/skills/ce-doc-review/references/document-intake.md +44 -0
- package/skills/ce-doc-review/references/findings-schema.json +85 -0
- package/skills/ce-doc-review/references/modes.md +20 -0
- package/skills/ce-doc-review/references/open-questions-defer.md +158 -0
- package/skills/ce-doc-review/references/persona-selection.md +41 -0
- package/skills/ce-doc-review/references/personas/adversarial-document-reviewer.md +109 -0
- package/skills/ce-doc-review/references/personas/coherence-reviewer.md +69 -0
- package/skills/ce-doc-review/references/personas/design-lens-reviewer.md +48 -0
- package/skills/ce-doc-review/references/personas/feasibility-reviewer.md +50 -0
- package/skills/ce-doc-review/references/personas/product-lens-reviewer.md +85 -0
- package/skills/ce-doc-review/references/personas/scope-guardian-reviewer.md +83 -0
- package/skills/ce-doc-review/references/personas/security-lens-reviewer.md +41 -0
- package/skills/ce-doc-review/references/personas/whole-doc-reviewer.md +25 -0
- package/skills/ce-doc-review/references/rendering-floor.md +175 -0
- package/skills/ce-doc-review/references/review-output-template.md +123 -0
- package/skills/ce-doc-review/references/subagent-template.md +188 -0
- package/skills/ce-doc-review/references/synthesis-and-presentation.md +350 -0
- package/skills/ce-doc-review/references/walkthrough.md +347 -0
- package/skills/ce-doc-review/scripts/cross-model-doc-review.sh +1270 -0
- package/skills/ce-doc-review/scripts/packs-resolve.py +737 -0
- package/skills/ce-doc-review/scripts/peer-job-runner.py +2594 -0
- package/skills/ce-dogfood/SKILL.md +66 -0
- package/skills/ce-dogfood/agents/openai.yaml +2 -0
- package/skills/ce-dogfood/references/dogfood-report-template.md +97 -0
- package/skills/ce-dogfood/references/phases.md +167 -0
- package/skills/ce-dogfood/references/test-matrix-taxonomy.md +62 -0
- package/skills/ce-dogfood/scripts/packs-resolve.py +737 -0
- package/skills/ce-explain/SKILL.md +81 -0
- package/skills/ce-explain/references/agents/behavior-trace-scout.md +19 -0
- package/skills/ce-explain/references/agents/work-recap-scout.md +23 -0
- package/skills/ce-explain/references/check-in.md +18 -0
- package/skills/ce-explain/references/destinations.md +35 -0
- package/skills/ce-explain/references/explainer-html.md +29 -0
- package/skills/ce-explain/references/explainer-markdown.md +24 -0
- package/skills/ce-explain/references/intake.md +50 -0
- package/skills/ce-explain/references/orchestration.md +46 -0
- package/skills/ce-handoff/SKILL.md +54 -0
- package/skills/ce-handoff/references/create.md +88 -0
- package/skills/ce-handoff/references/resume.md +46 -0
- package/skills/ce-ideate/SKILL.md +75 -0
- package/skills/ce-ideate/references/agents/issue-intelligence-analyst.md +166 -0
- package/skills/ce-ideate/references/agents/learnings-researcher.md +247 -0
- package/skills/ce-ideate/references/agents/slack-researcher.md +127 -0
- package/skills/ce-ideate/references/agents/web-researcher.md +121 -0
- package/skills/ce-ideate/references/decomposition.md +39 -0
- package/skills/ce-ideate/references/divergent-ideation.md +112 -0
- package/skills/ce-ideate/references/grounding.md +138 -0
- package/skills/ce-ideate/references/html-rendering.md +638 -0
- package/skills/ce-ideate/references/ideation-sections.md +191 -0
- package/skills/ce-ideate/references/issue-intelligence.md +44 -0
- package/skills/ce-ideate/references/markdown-rendering.md +242 -0
- package/skills/ce-ideate/references/output-mode.md +34 -0
- package/skills/ce-ideate/references/post-ideation-workflow.md +169 -0
- package/skills/ce-ideate/references/scope-gates.md +148 -0
- package/skills/ce-ideate/references/universal-ideation.md +119 -0
- package/skills/ce-ideate/references/user-research-artifacts.md +28 -0
- package/skills/ce-ideate/references/web-research-cache.md +56 -0
- package/skills/ce-noslop/SKILL.md +45 -0
- package/skills/ce-noslop/references/patterns.md +61 -0
- package/skills/ce-noslop/references/terminology.md +3 -0
- package/skills/ce-optimize/SKILL.md +64 -0
- package/skills/ce-optimize/references/agents/learnings-researcher.md +247 -0
- package/skills/ce-optimize/references/agents/repo-research-analyst.md +258 -0
- package/skills/ce-optimize/references/example-expensive-benchmark-spec.yaml +88 -0
- package/skills/ce-optimize/references/example-hard-spec.yaml +64 -0
- package/skills/ce-optimize/references/example-judge-spec.yaml +83 -0
- package/skills/ce-optimize/references/example-text-target-spec.yaml +80 -0
- package/skills/ce-optimize/references/experiment-log-schema.yaml +563 -0
- package/skills/ce-optimize/references/experiment-prompt-template.md +143 -0
- package/skills/ce-optimize/references/judge-prompt-template.md +117 -0
- package/skills/ce-optimize/references/loop.md +286 -0
- package/skills/ce-optimize/references/measurement.md +168 -0
- package/skills/ce-optimize/references/optimize-spec-schema.yaml +570 -0
- package/skills/ce-optimize/references/persistence.md +93 -0
- package/skills/ce-optimize/references/spec.md +107 -0
- package/skills/ce-optimize/references/text-targets.md +51 -0
- package/skills/ce-optimize/references/usage-guide.md +147 -0
- package/skills/ce-optimize/references/wrap-up.md +54 -0
- package/skills/ce-optimize/scripts/decide.mjs +676 -0
- package/skills/ce-optimize/scripts/experiment-worktree.sh +330 -0
- package/skills/ce-optimize/scripts/measure.sh +140 -0
- package/skills/ce-optimize/scripts/parallel-probe.sh +134 -0
- package/skills/ce-plan/SKILL.md +60 -0
- package/skills/ce-plan/references/agents/agent-native-planning-strategist.md +66 -0
- package/skills/ce-plan/references/agents/architecture-strategist.md +46 -0
- package/skills/ce-plan/references/agents/best-practices-researcher.md +118 -0
- package/skills/ce-plan/references/agents/data-integrity-guardian.md +68 -0
- package/skills/ce-plan/references/agents/framework-docs-researcher.md +97 -0
- package/skills/ce-plan/references/agents/git-history-analyzer.md +40 -0
- package/skills/ce-plan/references/agents/learnings-researcher.md +268 -0
- package/skills/ce-plan/references/agents/pattern-recognition-specialist.md +55 -0
- package/skills/ce-plan/references/agents/performance-oracle.md +108 -0
- package/skills/ce-plan/references/agents/repo-research-analyst.md +262 -0
- package/skills/ce-plan/references/agents/security-sentinel.md +91 -0
- package/skills/ce-plan/references/agents/slack-researcher.md +131 -0
- package/skills/ce-plan/references/agents/spec-flow-analyzer.md +84 -0
- package/skills/ce-plan/references/agents/web-researcher.md +125 -0
- package/skills/ce-plan/references/approach-altitude.md +55 -0
- package/skills/ce-plan/references/bakeoff.md +9 -0
- package/skills/ce-plan/references/deepening-workflow.md +263 -0
- package/skills/ce-plan/references/final-review.md +134 -0
- package/skills/ce-plan/references/html-rendering.md +638 -0
- package/skills/ce-plan/references/intake.md +158 -0
- package/skills/ce-plan/references/markdown-rendering.md +242 -0
- package/skills/ce-plan/references/output-contracts.md +29 -0
- package/skills/ce-plan/references/output-mode.md +45 -0
- package/skills/ce-plan/references/plan-handoff.md +116 -0
- package/skills/ce-plan/references/plan-sections.md +489 -0
- package/skills/ce-plan/references/reasoning-elevation.md +124 -0
- package/skills/ce-plan/references/research.md +211 -0
- package/skills/ce-plan/references/resume.md +61 -0
- package/skills/ce-plan/references/settled-decisions.md +45 -0
- package/skills/ce-plan/references/structure.md +207 -0
- package/skills/ce-plan/references/synthesis-summary.md +260 -0
- package/skills/ce-plan/references/universal-planning.md +170 -0
- package/skills/ce-plan/scripts/elevation-dispatch.sh +288 -0
- package/skills/ce-plan/scripts/packs-resolve.py +737 -0
- package/skills/ce-plan/scripts/peer-job-runner.py +2594 -0
- package/skills/ce-polish/SKILL.md +22 -0
- package/skills/ce-polish/agents/openai.yaml +2 -0
- package/skills/ce-polish/references/dev-server-astro.md +58 -0
- package/skills/ce-polish/references/dev-server-detection.md +40 -0
- package/skills/ce-polish/references/dev-server-next.md +61 -0
- package/skills/ce-polish/references/dev-server-nuxt.md +58 -0
- package/skills/ce-polish/references/dev-server-procfile.md +59 -0
- package/skills/ce-polish/references/dev-server-rails.md +50 -0
- package/skills/ce-polish/references/dev-server-remix.md +58 -0
- package/skills/ce-polish/references/dev-server-sveltekit.md +58 -0
- package/skills/ce-polish/references/dev-server-vite.md +48 -0
- package/skills/ce-polish/references/install-riffrec.md +35 -0
- package/skills/ce-polish/references/launch-json-schema.md +177 -0
- package/skills/ce-polish/references/live-loop.md +98 -0
- package/skills/ce-polish/references/live-remote.md +35 -0
- package/skills/ce-polish/references/live-start.md +93 -0
- package/skills/ce-polish/references/live-stream-contract.md +253 -0
- package/skills/ce-polish/references/run.md +67 -0
- package/skills/ce-polish/scripts/detect-project-type.sh +277 -0
- package/skills/ce-polish/scripts/detect-riffrec.sh +225 -0
- package/skills/ce-polish/scripts/live-endpoint.js +2841 -0
- package/skills/ce-polish/scripts/read-launch-json.sh +117 -0
- package/skills/ce-polish/scripts/resolve-package-manager.sh +95 -0
- package/skills/ce-polish/scripts/resolve-port.sh +307 -0
- package/skills/ce-pov/SKILL.md +64 -0
- package/skills/ce-pov/references/agents/external-evidence-researcher.md +26 -0
- package/skills/ce-pov/references/agents/pov-peer.md +43 -0
- package/skills/ce-pov/references/agents/precedent-activity-scout.md +21 -0
- package/skills/ce-pov/references/agents/project-grounding-scout.md +32 -0
- package/skills/ce-pov/references/boundaries.md +36 -0
- package/skills/ce-pov/references/cross-model-panel.md +596 -0
- package/skills/ce-pov/references/followup.md +9 -0
- package/skills/ce-pov/references/grounding.md +47 -0
- package/skills/ce-pov/references/intake.md +61 -0
- package/skills/ce-pov/references/invocation.md +47 -0
- package/skills/ce-pov/references/method.md +68 -0
- package/skills/ce-pov/references/pov-schema.json +56 -0
- package/skills/ce-pov/references/report.md +7 -0
- package/skills/ce-pov/scripts/cross-model-pov.sh +1110 -0
- package/skills/ce-pov/scripts/peer-job-runner.py +2594 -0
- package/skills/ce-product-pulse/SKILL.md +81 -0
- package/skills/ce-product-pulse/agents/openai.yaml +2 -0
- package/skills/ce-product-pulse/references/config.md +20 -0
- package/skills/ce-product-pulse/references/interview.md +260 -0
- package/skills/ce-product-pulse/references/report-template.md +89 -0
- package/skills/ce-product-pulse/references/run.md +46 -0
- package/skills/ce-product-pulse/references/setup.md +43 -0
- package/skills/ce-promote/SKILL.md +90 -0
- package/skills/ce-promote/agents/openai.yaml +2 -0
- package/skills/ce-promote/references/spiral-cli.md +149 -0
- package/skills/ce-proof/SKILL.md +65 -0
- package/skills/ce-proof/references/api.md +176 -0
- package/skills/ce-proof/references/workflows.md +124 -0
- package/skills/ce-prototype/SKILL.md +59 -0
- package/skills/ce-prototype/assets/annotate.css +206 -0
- package/skills/ce-prototype/assets/annotate.js +837 -0
- package/skills/ce-prototype/references/annotation-loop.md +32 -0
- package/skills/ce-prototype/references/build.md +39 -0
- package/skills/ce-prototype/references/craft-floor.md +43 -0
- package/skills/ce-prototype/references/preview.md +118 -0
- package/skills/ce-prototype/references/scoping.md +38 -0
- package/skills/ce-prototype/references/write-back.md +37 -0
- package/skills/ce-prototype/scripts/light-webserver.js +1275 -0
- package/skills/ce-resolve-pr-feedback/SKILL.md +60 -0
- package/skills/ce-resolve-pr-feedback/references/agents/pr-comment-resolver.md +59 -0
- package/skills/ce-resolve-pr-feedback/references/evaluation-rubric.md +141 -0
- package/skills/ce-resolve-pr-feedback/references/full-mode.md +336 -0
- package/skills/ce-resolve-pr-feedback/references/pipeline-mode.md +23 -0
- package/skills/ce-resolve-pr-feedback/references/resume.md +60 -0
- package/skills/ce-resolve-pr-feedback/references/return-to-caller.md +111 -0
- package/skills/ce-resolve-pr-feedback/references/targeted-mode.md +48 -0
- package/skills/ce-resolve-pr-feedback/scripts/get-pr-comments +176 -0
- package/skills/ce-resolve-pr-feedback/scripts/get-thread-for-comment +84 -0
- package/skills/ce-resolve-pr-feedback/scripts/pending-feedback.py +287 -0
- package/skills/ce-resolve-pr-feedback/scripts/reply-to-pr-thread +57 -0
- package/skills/ce-resolve-pr-feedback/scripts/resolve-pr-thread +23 -0
- package/skills/ce-retune/SKILL.md +42 -0
- package/skills/ce-retune/agents/openai.yaml +2 -0
- package/skills/ce-retune/references/baseline-mining.md +122 -0
- package/skills/ce-retune/references/corpus-audit.md +128 -0
- package/skills/ce-retune/references/cut-passes.md +129 -0
- package/skills/ce-retune/references/halt-taxonomy.md +123 -0
- package/skills/ce-retune/references/noise-floor.md +131 -0
- package/skills/ce-retune/references/workflow-shapes.md +73 -0
- package/skills/ce-riffrec-feedback-analysis/SKILL.md +33 -0
- package/skills/ce-riffrec-feedback-analysis/references/analyzer.md +18 -0
- package/skills/ce-riffrec-feedback-analysis/references/compound-engineering-feedback-format.md +116 -0
- package/skills/ce-riffrec-feedback-analysis/references/extensive-analysis.md +98 -0
- package/skills/ce-riffrec-feedback-analysis/references/install-riffrec.md +27 -0
- package/skills/ce-riffrec-feedback-analysis/references/quick-bug-report.md +38 -0
- package/skills/ce-riffrec-feedback-analysis/scripts/analyze_riffrec_zip.py +1306 -0
- package/skills/ce-setup/SKILL.md +103 -0
- package/skills/ce-setup/agents/openai.yaml +2 -0
- package/skills/ce-setup/assets/compounding-directive.md +11 -0
- package/skills/ce-setup/assets/noslop-directive.md +7 -0
- package/skills/ce-setup/assets/pack-rule-template.md +11 -0
- package/skills/ce-setup/references/acpx-cache-warm.md +14 -0
- package/skills/ce-setup/references/config-template.yaml +210 -0
- package/skills/ce-setup/references/legacy-codex-tool-map.md +15 -0
- package/skills/ce-setup/references/pack-scaffold.md +45 -0
- package/skills/ce-setup/references/repo-fixes.md +121 -0
- package/skills/ce-setup/scripts/check-health +929 -0
- package/skills/ce-setup/scripts/packs-resolve.py +737 -0
- package/skills/ce-simplify-code/SKILL.md +76 -0
- package/skills/ce-simplify-code/references/personas/code-quality-reviewer.md +17 -0
- package/skills/ce-simplify-code/references/personas/code-reuse-reviewer.md +7 -0
- package/skills/ce-simplify-code/references/personas/comment-reviewer.md +24 -0
- package/skills/ce-simplify-code/references/personas/efficiency-reviewer.md +11 -0
- package/skills/ce-simplify-code/references/personas/test-value-reviewer.md +23 -0
- package/skills/ce-simplify-code/references/reviewer-dispatch.md +11 -0
- package/skills/ce-simplify-code/references/standalone-report.md +25 -0
- package/skills/ce-strategy/SKILL.md +61 -0
- package/skills/ce-strategy/references/grounding.md +22 -0
- package/skills/ce-strategy/references/interview.md +179 -0
- package/skills/ce-strategy/references/strategy-template.md +94 -0
- package/skills/ce-strategy/references/update-run.md +33 -0
- package/skills/ce-sweep/SKILL.md +93 -0
- package/skills/ce-sweep/agents/openai.yaml +2 -0
- package/skills/ce-sweep/references/agents/media-analyzer.md +54 -0
- package/skills/ce-sweep/references/interview.md +208 -0
- package/skills/ce-sweep/references/model-tiers.md +13 -0
- package/skills/ce-sweep/references/plan-template.md +62 -0
- package/skills/ce-sweep/references/run.md +126 -0
- package/skills/ce-sweep/references/sources/email.md +57 -0
- package/skills/ce-sweep/references/sources/github-issues.md +59 -0
- package/skills/ce-sweep/references/sources/slack.md +61 -0
- package/skills/ce-sweep/references/state-schema.md +157 -0
- package/skills/ce-sweep/references/subagent-template.md +60 -0
- package/skills/ce-sweep/scripts/analyze_riffrec_zip.py +1306 -0
- package/skills/ce-sweep/scripts/sweep-state.py +793 -0
- package/skills/ce-test-browser/SKILL.md +50 -0
- package/skills/ce-test-browser/references/agent-browser-driver.md +47 -0
- package/skills/ce-test-browser/references/pipeline-orchestration.md +45 -0
- package/skills/ce-test-browser/references/route-and-report.md +129 -0
- package/skills/ce-test-browser/scripts/resolve-port.sh +41 -0
- package/skills/ce-test-xcode/SKILL.md +26 -0
- package/skills/ce-test-xcode/agents/openai.yaml +2 -0
- package/skills/ce-test-xcode/references/setup-and-build.md +32 -0
- package/skills/ce-test-xcode/references/test-and-report.md +64 -0
- package/skills/ce-work/SKILL.md +62 -0
- package/skills/ce-work/references/agents/figma-design-sync.md +27 -0
- package/skills/ce-work/references/agents/implementation-worker.md +17 -0
- package/skills/ce-work/references/cross-model-execution.md +191 -0
- package/skills/ce-work/references/execution-engines.md +64 -0
- package/skills/ce-work/references/execution-strategy.md +73 -0
- package/skills/ce-work/references/implementation-loop.md +107 -0
- package/skills/ce-work/references/implementation-result-schema.json +52 -0
- package/skills/ce-work/references/input-triage.md +50 -0
- package/skills/ce-work/references/non-code-execution.md +23 -0
- package/skills/ce-work/references/return-to-caller.md +33 -0
- package/skills/ce-work/references/review-findings-followup.md +82 -0
- package/skills/ce-work/references/shipping-workflow.md +89 -0
- package/skills/ce-work/references/tracker-defer.md +150 -0
- package/skills/ce-work/references/work-intake.md +51 -0
- package/skills/ce-work/references/workspace-setup.md +27 -0
- package/skills/ce-work/scripts/__pycache__/unit_workspace_jobs.cpython-314.pyc +0 -0
- package/skills/ce-work/scripts/__pycache__/unit_workspace_state.cpython-314.pyc +0 -0
- package/skills/ce-work/scripts/cross-model-work.sh +1385 -0
- package/skills/ce-work/scripts/peer-job-runner.py +2594 -0
- package/skills/ce-work/scripts/unit-workspace.py +215 -0
- package/skills/ce-work/scripts/unit_workspace_ignored.py +93 -0
- package/skills/ce-work/scripts/unit_workspace_integration.py +677 -0
- package/skills/ce-work/scripts/unit_workspace_jobs.py +1216 -0
- package/skills/ce-work/scripts/unit_workspace_lifecycle.py +981 -0
- package/skills/ce-work/scripts/unit_workspace_state.py +1379 -0
- package/skills/ce-work/scripts/unit_workspace_transaction.py +612 -0
- package/skills/ce-worktree/SKILL.md +54 -0
- package/skills/lfg/SKILL.md +59 -0
- package/skills/lfg/references/debug-return.md +25 -0
- package/skills/lfg/references/intake.md +30 -0
- package/skills/lfg/references/next-work-handoff.md +96 -0
- package/skills/lfg/references/plan-brief.md +36 -0
- package/skills/lfg/references/review-followup.md +78 -0
- package/skills/lfg/references/shipping.md +65 -0
- package/skills/lfg/references/stage-routing.md +49 -0
- package/skills/lfg/references/task-visibility.md +11 -0
- package/skills/lfg/references/tracker-defer.md +150 -0
- package/skills/lfg/references/work-return.md +27 -0
- package/skills/wtf/SKILL.md +33 -0
- package/skills/wtf/agents/openai.yaml +2 -0
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Validate cited claims in a solution doc against the git tree.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
python3 validate-doc-claims.py <doc-path>
|
|
6
|
+
|
|
7
|
+
Exit codes:
|
|
8
|
+
0 — nothing flagged
|
|
9
|
+
1 — one or more flags need adjudication (report on stdout)
|
|
10
|
+
2 — usage error (bad arguments, missing file)
|
|
11
|
+
|
|
12
|
+
Scope: mechanical grounding checks on a written doc's *body*. Complements
|
|
13
|
+
validate-frontmatter.py (parser-safety) — this script checks the body's
|
|
14
|
+
citations against the repository:
|
|
15
|
+
|
|
16
|
+
1. Cited repo-relative paths (backticked, containing at least one '/')
|
|
17
|
+
exist in the working tree, including already-absolute citations that
|
|
18
|
+
fall inside the repo (rewritten to repo-relative before candidacy).
|
|
19
|
+
Tokens containing '../' resolve from the doc's directory (those
|
|
20
|
+
escaping the repo are skipped). Misses tracked at HEAD or the
|
|
21
|
+
upstream default branch still count as real paths and are classified
|
|
22
|
+
(deleted/uncommitted vs stale checkout). Tokens missing everywhere
|
|
23
|
+
are flagged only when path-shaped; slash-delimited identifiers
|
|
24
|
+
(branch names, git refs, provider/model IDs) and slash-prefixed
|
|
25
|
+
URL routes are skipped.
|
|
26
|
+
2. Cited commit SHAs (7-40 hex chars with at least one digit and one
|
|
27
|
+
a-f letter) resolve to commits, classified by reachability from
|
|
28
|
+
HEAD and the upstream default branch. Session ids, content hashes
|
|
29
|
+
and blob hashes are hex too, so an unresolvable hex word is
|
|
30
|
+
reported in one of two tiers rather than asserted to be fabricated:
|
|
31
|
+
FLAG when the text right before it presents it as a commit (a
|
|
32
|
+
likely fabricated citation), NOTE otherwise (an identifier this
|
|
33
|
+
script cannot classify). Only FLAG affects the exit code. The
|
|
34
|
+
cue vocabulary therefore ranks confidence; it does not decide
|
|
35
|
+
whether an item is surfaced, so a phrasing it misses is reported
|
|
36
|
+
one tier down instead of disappearing.
|
|
37
|
+
3. Relative markdown link targets resolve from the doc's location.
|
|
38
|
+
4. Dangling drafting scaffold: "Learning(s) N" numbering and
|
|
39
|
+
unresolved {{...}} placeholder tokens. Inline code spans and fenced
|
|
40
|
+
code blocks are masked first, so a {{...}} shown as documented syntax
|
|
41
|
+
(Handlebars, a CI variable, a GitHub ruleset placeholder) is not
|
|
42
|
+
mistaken for a leaked scaffold; only a bare token in prose is flagged.
|
|
43
|
+
|
|
44
|
+
Flags are adjudication input, NOT hard failures — a doc may legitimately
|
|
45
|
+
cite a path deleted by the very fix it documents. The calling agent
|
|
46
|
+
decides per flag: fix, annotate as historical, or confirm intentional.
|
|
47
|
+
Only the summary exit code distinguishes "clean" from "needs a look".
|
|
48
|
+
|
|
49
|
+
The script never touches the network (no fetch); classification uses
|
|
50
|
+
whatever refs exist locally. Run a best-effort `git fetch --quiet` first
|
|
51
|
+
when freshness matters. Pure stdlib (no third-party deps).
|
|
52
|
+
"""
|
|
53
|
+
import os
|
|
54
|
+
import re
|
|
55
|
+
import subprocess
|
|
56
|
+
import sys
|
|
57
|
+
|
|
58
|
+
# Tokens containing these are placeholders/examples, not real citations.
|
|
59
|
+
PLACEHOLDER_CHARS = set("<>{}*$")
|
|
60
|
+
PLACEHOLDER_SUBSTRINGS = ("path/to", "...", "…")
|
|
61
|
+
|
|
62
|
+
SHA_RE = re.compile(r"\b[0-9a-f]{7,40}\b")
|
|
63
|
+
# Words that name a commit or a commit operation, so a hex token right after
|
|
64
|
+
# one is a commit citation. Words naming some other git object ("blob", "tree"),
|
|
65
|
+
# any hash ("sha"), and the bare tool name ("git", which precedes every object
|
|
66
|
+
# kind equally) are deliberately absent — they are what the flag used to mistake
|
|
67
|
+
# for commits.
|
|
68
|
+
COMMIT_WORDS = frozenset(
|
|
69
|
+
"commit commits committed committing revision revisions rev revs "
|
|
70
|
+
"revert reverts reverted cherry-pick cherry-picked rebase rebased "
|
|
71
|
+
"bisect bisected".split()
|
|
72
|
+
)
|
|
73
|
+
# A hex token is also a citation when the sentence attributes a change landing
|
|
74
|
+
# in this repository to it: "landed in <sha>", "resolved by <sha>". Both halves
|
|
75
|
+
# are needed. The preposition alone attributes without saying what to, so it
|
|
76
|
+
# would read "recorded at <digest>" as a commit; the verb alone does not point
|
|
77
|
+
# at the token. Membership below is that condition, not a tally of phrasings
|
|
78
|
+
# seen so far: a verb belongs when it says a change landed, and does not when
|
|
79
|
+
# it says an identifier was assigned or a value stored.
|
|
80
|
+
CITATION_VERBS = frozenset(
|
|
81
|
+
"fixed fix fixes landed lands land introduced introduces introduce "
|
|
82
|
+
"shipped ships ship merged merges merge resolved resolves resolve "
|
|
83
|
+
"reverted reverts broke breaks broken caused causes regressed "
|
|
84
|
+
"added adds removed removes released releases".split()
|
|
85
|
+
)
|
|
86
|
+
CITATION_PREPS = frozenset(("in", "by", "at", "with"))
|
|
87
|
+
# The pin form that names a commit is owner/repo@<sha>. A bare "@" is not it:
|
|
88
|
+
# it also prefixes account names and image tags, whose identifiers are hex too.
|
|
89
|
+
REPO_PIN_RE = re.compile(r"(?<![\w./@-])[\w.-]+/[\w.-]+@$")
|
|
90
|
+
BACKTICK_RE = re.compile(r"`([^`\n]+)`")
|
|
91
|
+
MD_LINK_RE = re.compile(r"\[[^\]]*\]\(([^)\s]+)\)")
|
|
92
|
+
FENCE_RE = re.compile(r"^\s*(`{3,}|~{3,})(.*)$")
|
|
93
|
+
SCAFFOLD_RES = (
|
|
94
|
+
re.compile(r"\bLearnings?\s+#?\d"),
|
|
95
|
+
re.compile(r"\{\{[^}\n]*\}\}"),
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def usage_fail(msg: str) -> "NoReturn":
|
|
100
|
+
sys.stderr.write(f"validate-doc-claims: {msg}\n")
|
|
101
|
+
sys.exit(2)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def git(args: list[str], cwd: str) -> tuple[int, str]:
|
|
105
|
+
try:
|
|
106
|
+
result = subprocess.run(
|
|
107
|
+
["git", *args],
|
|
108
|
+
cwd=cwd,
|
|
109
|
+
capture_output=True,
|
|
110
|
+
text=True,
|
|
111
|
+
timeout=30,
|
|
112
|
+
)
|
|
113
|
+
return result.returncode, result.stdout.strip()
|
|
114
|
+
except (OSError, subprocess.TimeoutExpired):
|
|
115
|
+
return 1, ""
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def split_body(text: str) -> tuple[str, int]:
|
|
119
|
+
"""Return (body, 1-indexed line number the body starts on).
|
|
120
|
+
|
|
121
|
+
Skips YAML frontmatter when present so frontmatter fields are not
|
|
122
|
+
scanned as body citations.
|
|
123
|
+
"""
|
|
124
|
+
lines = text.split("\n")
|
|
125
|
+
if lines and lines[0].rstrip() == "---":
|
|
126
|
+
for i in range(1, len(lines)):
|
|
127
|
+
if lines[i].rstrip() == "---":
|
|
128
|
+
return "\n".join(lines[i + 1 :]), i + 2
|
|
129
|
+
return text, 1
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def is_path_candidate(token: str, *, known_path: bool = False) -> bool:
|
|
133
|
+
if any(ch.isspace() for ch in token):
|
|
134
|
+
return False
|
|
135
|
+
if not known_path and "/" not in token:
|
|
136
|
+
return False
|
|
137
|
+
if "://" in token or token.startswith(("http", "#", "/", "~")):
|
|
138
|
+
return False
|
|
139
|
+
if token.startswith(("origin/", "upstream/", "refs/")):
|
|
140
|
+
return False # git refs, not repo paths
|
|
141
|
+
if PLACEHOLDER_CHARS & set(token):
|
|
142
|
+
return False
|
|
143
|
+
if any(sub in token for sub in PLACEHOLDER_SUBSTRINGS):
|
|
144
|
+
return False
|
|
145
|
+
return True
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def is_path_shaped(token: str, base: str) -> bool:
|
|
149
|
+
"""Distinguish a path citation from a slash-delimited identifier
|
|
150
|
+
(branch name, provider/model ID) among tokens found nowhere in git."""
|
|
151
|
+
segments = token.split("/")
|
|
152
|
+
if re.search(r"\.[A-Za-z0-9]{1,8}$", segments[-1]):
|
|
153
|
+
return True
|
|
154
|
+
if token.endswith("/"):
|
|
155
|
+
return True
|
|
156
|
+
return os.path.isdir(os.path.join(base, segments[0]))
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def mask_code(lines: list[str]) -> list[str]:
|
|
160
|
+
"""Blank out fenced code blocks and inline code spans, preserving line
|
|
161
|
+
count and length. Illustrative {{...}} in quoted code must not read as a
|
|
162
|
+
leaked drafting scaffold; only bare tokens in prose should."""
|
|
163
|
+
masked: list[str] = []
|
|
164
|
+
fence: str | None = None # active fence run (e.g. "```"), or None
|
|
165
|
+
for line in lines:
|
|
166
|
+
m = FENCE_RE.match(line)
|
|
167
|
+
if fence is None and m:
|
|
168
|
+
fence = m.group(1)
|
|
169
|
+
masked.append(" " * len(line))
|
|
170
|
+
continue
|
|
171
|
+
if fence is not None:
|
|
172
|
+
# CommonMark: a closing fence is the same char, at least as long,
|
|
173
|
+
# and followed only by whitespace — an info string (```json) opens
|
|
174
|
+
# but never closes, so it stays block content.
|
|
175
|
+
if (
|
|
176
|
+
m
|
|
177
|
+
and m.group(1)[0] == fence[0]
|
|
178
|
+
and len(m.group(1)) >= len(fence)
|
|
179
|
+
and not m.group(2).strip()
|
|
180
|
+
):
|
|
181
|
+
fence = None
|
|
182
|
+
masked.append(" " * len(line))
|
|
183
|
+
continue
|
|
184
|
+
masked.append(BACKTICK_RE.sub(lambda x: " " * len(x.group(0)), line))
|
|
185
|
+
return masked
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def cites_a_commit(prefix: str) -> bool:
|
|
189
|
+
"""True when the text just before a hex word presents it as a commit.
|
|
190
|
+
|
|
191
|
+
Only the last few words on the same line count: a cue further away
|
|
192
|
+
("the git history shows session 7e6861b4") describes the surroundings,
|
|
193
|
+
not the token. Digits are word characters so a hash named after its
|
|
194
|
+
algorithm ("SHA256") stays one non-cue word, and command flags drop out
|
|
195
|
+
first so `git show --format=%H <sha>` reads like `git show <sha>`.
|
|
196
|
+
"""
|
|
197
|
+
if REPO_PIN_RE.search(prefix):
|
|
198
|
+
return True # owner/repo@<sha> pins a commit
|
|
199
|
+
unflagged = " ".join(w for w in prefix.split() if not w.startswith("-"))
|
|
200
|
+
words = [
|
|
201
|
+
w.lower() for w in re.findall(r"[A-Za-z][A-Za-z0-9-]*", unflagged)[-3:]
|
|
202
|
+
]
|
|
203
|
+
if any(word in COMMIT_WORDS for word in words):
|
|
204
|
+
return True
|
|
205
|
+
return (
|
|
206
|
+
len(words) >= 2
|
|
207
|
+
and words[-1] in CITATION_PREPS
|
|
208
|
+
and words[-2] in CITATION_VERBS
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def normalize_path(token: str) -> str:
|
|
213
|
+
token = token.strip().rstrip(".,;")
|
|
214
|
+
token = re.sub(r":\d+(-\d+)?$", "", token) # strip `:line` / `:a-b` refs
|
|
215
|
+
if token.startswith("./"):
|
|
216
|
+
token = token[2:]
|
|
217
|
+
return token
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def strip_repo_prefix(token: str, base: str) -> str:
|
|
221
|
+
"""Rewrite an already-absolute path inside the repo to repo-relative.
|
|
222
|
+
|
|
223
|
+
Relative tokens, URL routes, and out-of-repo absolute paths are
|
|
224
|
+
unchanged so the existing candidacy guard still drops them. Realpath
|
|
225
|
+
both sides so a host where /tmp is a symlink still matches. A
|
|
226
|
+
successful rewrite is slash-normalized so Windows relpath output
|
|
227
|
+
stays a candidate.
|
|
228
|
+
"""
|
|
229
|
+
if not os.path.isabs(token):
|
|
230
|
+
return token
|
|
231
|
+
try:
|
|
232
|
+
rel = os.path.relpath(os.path.realpath(token), os.path.realpath(base))
|
|
233
|
+
except ValueError:
|
|
234
|
+
return token
|
|
235
|
+
if rel == ".." or rel.startswith(".." + os.sep):
|
|
236
|
+
return token
|
|
237
|
+
return rel.replace("\\", "/")
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def main(argv: list[str]) -> int:
|
|
241
|
+
if len(argv) != 2:
|
|
242
|
+
usage_fail(f"usage: {os.path.basename(argv[0])} <doc-path>")
|
|
243
|
+
|
|
244
|
+
doc_path = argv[1]
|
|
245
|
+
if not os.path.isfile(doc_path):
|
|
246
|
+
usage_fail(f"file not found: {doc_path}")
|
|
247
|
+
|
|
248
|
+
with open(doc_path, encoding="utf-8") as f:
|
|
249
|
+
text = f.read()
|
|
250
|
+
|
|
251
|
+
doc_dir = os.path.dirname(os.path.abspath(doc_path))
|
|
252
|
+
body, body_start = split_body(text)
|
|
253
|
+
body_lines = body.split("\n")
|
|
254
|
+
|
|
255
|
+
def loc_suffix(needle: str) -> str:
|
|
256
|
+
for i, line in enumerate(body_lines):
|
|
257
|
+
if needle in line:
|
|
258
|
+
return f" (line {body_start + i})"
|
|
259
|
+
return ""
|
|
260
|
+
|
|
261
|
+
infos: list[str] = []
|
|
262
|
+
notes: list[str] = []
|
|
263
|
+
flags: list[str] = []
|
|
264
|
+
|
|
265
|
+
# --- Repo context -----------------------------------------------------
|
|
266
|
+
code, repo_root = git(["rev-parse", "--show-toplevel"], doc_dir)
|
|
267
|
+
in_git = code == 0 and bool(repo_root)
|
|
268
|
+
upstream: str | None = None
|
|
269
|
+
if in_git:
|
|
270
|
+
code, ref = git(["rev-parse", "--abbrev-ref", "origin/HEAD"], repo_root)
|
|
271
|
+
if code == 0 and ref:
|
|
272
|
+
upstream = ref
|
|
273
|
+
else:
|
|
274
|
+
for candidate in ("origin/main", "origin/master"):
|
|
275
|
+
code, _ = git(
|
|
276
|
+
["rev-parse", "--verify", "--quiet", candidate], repo_root
|
|
277
|
+
)
|
|
278
|
+
if code == 0:
|
|
279
|
+
upstream = candidate
|
|
280
|
+
break
|
|
281
|
+
if upstream:
|
|
282
|
+
code, behind = git(
|
|
283
|
+
["rev-list", "--count", f"HEAD..{upstream}"], repo_root
|
|
284
|
+
)
|
|
285
|
+
if code == 0 and behind.isdigit() and int(behind) > 0:
|
|
286
|
+
infos.append(
|
|
287
|
+
f"INFO: worktree is {behind} commits behind {upstream} — "
|
|
288
|
+
"verify merge-state claims against remote truth (gh pr view), "
|
|
289
|
+
"not this checkout"
|
|
290
|
+
)
|
|
291
|
+
else:
|
|
292
|
+
infos.append(
|
|
293
|
+
"INFO: no upstream default branch found — "
|
|
294
|
+
"path/SHA classification limited to HEAD"
|
|
295
|
+
)
|
|
296
|
+
else:
|
|
297
|
+
infos.append(
|
|
298
|
+
"INFO: not a git repository — path and SHA classification skipped "
|
|
299
|
+
"(scaffold and link checks still apply)"
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
def upstream_has_path(path: str) -> bool:
|
|
303
|
+
if not (in_git and upstream):
|
|
304
|
+
return False
|
|
305
|
+
code, _ = git(["cat-file", "-e", f"{upstream}:{path}"], repo_root)
|
|
306
|
+
return code == 0
|
|
307
|
+
|
|
308
|
+
def head_has_path(path: str) -> bool:
|
|
309
|
+
if not in_git:
|
|
310
|
+
return False
|
|
311
|
+
code, _ = git(["cat-file", "-e", f"HEAD:{path}"], repo_root)
|
|
312
|
+
return code == 0
|
|
313
|
+
|
|
314
|
+
# --- 1. Cited repo paths ----------------------------------------------
|
|
315
|
+
checked_paths = 0
|
|
316
|
+
seen_paths: set[str] = set()
|
|
317
|
+
base = repo_root if in_git else os.getcwd()
|
|
318
|
+
for raw in BACKTICK_RE.findall(body):
|
|
319
|
+
token = normalize_path(raw)
|
|
320
|
+
rewritten_abs = False
|
|
321
|
+
if in_git:
|
|
322
|
+
before = token
|
|
323
|
+
token = strip_repo_prefix(token, base)
|
|
324
|
+
rewritten_abs = token != before
|
|
325
|
+
if not is_path_candidate(token, known_path=rewritten_abs):
|
|
326
|
+
continue
|
|
327
|
+
check = token
|
|
328
|
+
if token.startswith("../") or "/../" in token:
|
|
329
|
+
# A `../` citation is doc-relative (matching how markdown links
|
|
330
|
+
# resolve), so map it to a repo-root path before checking.
|
|
331
|
+
if not in_git:
|
|
332
|
+
continue
|
|
333
|
+
resolved = os.path.realpath(os.path.join(doc_dir, token))
|
|
334
|
+
check = os.path.relpath(resolved, os.path.realpath(base))
|
|
335
|
+
if check.startswith(".."):
|
|
336
|
+
continue # escapes the repo — not checkable as a repo path
|
|
337
|
+
if check in seen_paths:
|
|
338
|
+
continue
|
|
339
|
+
seen_paths.add(check)
|
|
340
|
+
if os.path.exists(os.path.join(base, check)):
|
|
341
|
+
checked_paths += 1
|
|
342
|
+
continue
|
|
343
|
+
tracked_head = head_has_path(check)
|
|
344
|
+
tracked_upstream = upstream_has_path(check)
|
|
345
|
+
if not (tracked_head or tracked_upstream) and not is_path_shaped(
|
|
346
|
+
check, base
|
|
347
|
+
):
|
|
348
|
+
continue # branch name / provider ID, not a path citation
|
|
349
|
+
checked_paths += 1
|
|
350
|
+
loc = loc_suffix(raw)
|
|
351
|
+
if tracked_head:
|
|
352
|
+
flags.append(
|
|
353
|
+
f"FLAG path `{token}`{loc} — tracked at HEAD but missing from "
|
|
354
|
+
"the working tree: deleted or uncommitted removal? Annotate as "
|
|
355
|
+
"historical (e.g. removed by this fix) or restore it."
|
|
356
|
+
)
|
|
357
|
+
elif tracked_upstream:
|
|
358
|
+
flags.append(
|
|
359
|
+
f"FLAG path `{token}`{loc} — not in working tree but exists at "
|
|
360
|
+
f"{upstream}: stale checkout? Annotate or verify against upstream."
|
|
361
|
+
)
|
|
362
|
+
else:
|
|
363
|
+
where = (
|
|
364
|
+
f"working tree or {upstream}" if upstream else "working tree"
|
|
365
|
+
)
|
|
366
|
+
flags.append(
|
|
367
|
+
f"FLAG path `{token}`{loc} — not found in {where}. Fix the "
|
|
368
|
+
"citation, or annotate it as historical (e.g. removed by this fix)."
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
# --- 2. Cited commit SHAs ----------------------------------------------
|
|
372
|
+
checked_shas = 0
|
|
373
|
+
if in_git:
|
|
374
|
+
# One entry per distinct hex word: the line to report it at, and
|
|
375
|
+
# whether any occurrence of it is presented as a commit. A doc often
|
|
376
|
+
# quotes a token in a transcript before citing it, so a later citing
|
|
377
|
+
# occurrence upgrades the tier and supplies the line.
|
|
378
|
+
seen_shas: dict[str, tuple[int, bool]] = {}
|
|
379
|
+
order: list[str] = []
|
|
380
|
+
for m in SHA_RE.finditer(body):
|
|
381
|
+
sha = m.group(0)
|
|
382
|
+
if not (any(c.isdigit() for c in sha) and any(c in "abcdef" for c in sha)):
|
|
383
|
+
continue # dates and decimal ids are not SHAs
|
|
384
|
+
line_start = body.rfind("\n", 0, m.start()) + 1
|
|
385
|
+
cited = cites_a_commit(body[line_start : m.start()])
|
|
386
|
+
line_no = body_start + body.count("\n", 0, m.start())
|
|
387
|
+
if sha not in seen_shas:
|
|
388
|
+
seen_shas[sha] = (line_no, cited)
|
|
389
|
+
order.append(sha)
|
|
390
|
+
elif cited and not seen_shas[sha][1]:
|
|
391
|
+
seen_shas[sha] = (line_no, True)
|
|
392
|
+
for sha in order:
|
|
393
|
+
line_no, cited = seen_shas[sha]
|
|
394
|
+
code, _ = git(["cat-file", "-e", f"{sha}^{{commit}}"], repo_root)
|
|
395
|
+
resolved = code == 0
|
|
396
|
+
loc = f" (line {line_no})"
|
|
397
|
+
if not resolved:
|
|
398
|
+
if not cited:
|
|
399
|
+
# Nothing here says "commit", and hex is also how session
|
|
400
|
+
# ids and content hashes are written. Surface it without
|
|
401
|
+
# claiming to know which it is; the reader adjudicates.
|
|
402
|
+
notes.append(
|
|
403
|
+
f"NOTE sha {sha}{loc} — an unresolved hex identifier "
|
|
404
|
+
"with no commit reference around it. This script cannot "
|
|
405
|
+
"tell a session id or content hash from a commit; verify "
|
|
406
|
+
"it if it was meant as one."
|
|
407
|
+
)
|
|
408
|
+
continue
|
|
409
|
+
checked_shas += 1
|
|
410
|
+
flags.append(
|
|
411
|
+
f"FLAG sha {sha}{loc} — does not resolve to a commit in this "
|
|
412
|
+
"repository. Replace with the PR number, or drop it."
|
|
413
|
+
)
|
|
414
|
+
continue
|
|
415
|
+
checked_shas += 1
|
|
416
|
+
in_head = (
|
|
417
|
+
git(["merge-base", "--is-ancestor", sha, "HEAD"], repo_root)[0] == 0
|
|
418
|
+
)
|
|
419
|
+
in_up = (
|
|
420
|
+
upstream is not None
|
|
421
|
+
and git(["merge-base", "--is-ancestor", sha, upstream], repo_root)[0]
|
|
422
|
+
== 0
|
|
423
|
+
)
|
|
424
|
+
if in_head and (in_up or upstream is None):
|
|
425
|
+
continue
|
|
426
|
+
if in_head and not in_up:
|
|
427
|
+
flags.append(
|
|
428
|
+
f"FLAG sha {sha}{loc} — reachable from HEAD but not {upstream}: "
|
|
429
|
+
"local-only commit whose SHA may be rewritten on merge "
|
|
430
|
+
"(rebase/squash). Prefer citing the PR number."
|
|
431
|
+
)
|
|
432
|
+
elif in_up:
|
|
433
|
+
flags.append(
|
|
434
|
+
f"FLAG sha {sha}{loc} — not reachable from HEAD but reachable "
|
|
435
|
+
f"from {upstream}: this checkout predates the merge. Add a "
|
|
436
|
+
"temporal qualifier or verify the claim via gh."
|
|
437
|
+
)
|
|
438
|
+
else:
|
|
439
|
+
flags.append(
|
|
440
|
+
f"FLAG sha {sha}{loc} — exists but unreachable from HEAD"
|
|
441
|
+
+ (f" or {upstream}" if upstream else "")
|
|
442
|
+
+ ": likely a rebased-away commit. Prefer citing the PR number."
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
# --- 3. Relative markdown links -----------------------------------------
|
|
446
|
+
checked_links = 0
|
|
447
|
+
seen_links: set[str] = set()
|
|
448
|
+
for target in MD_LINK_RE.findall(body):
|
|
449
|
+
if re.match(r"^[a-z][a-z0-9+.-]*:", target, re.IGNORECASE):
|
|
450
|
+
continue # URL scheme
|
|
451
|
+
if target.startswith("#"):
|
|
452
|
+
continue # intra-doc anchor
|
|
453
|
+
bare = target.split("#", 1)[0]
|
|
454
|
+
if not bare or bare in seen_links:
|
|
455
|
+
continue
|
|
456
|
+
seen_links.add(bare)
|
|
457
|
+
checked_links += 1
|
|
458
|
+
if not os.path.exists(os.path.normpath(os.path.join(doc_dir, bare))):
|
|
459
|
+
loc = loc_suffix(target)
|
|
460
|
+
flags.append(
|
|
461
|
+
f"FLAG link ({target}){loc} — relative target does not resolve "
|
|
462
|
+
"from the doc's location. Fix the path."
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
# --- 4. Dangling drafting scaffold ---------------------------------------
|
|
466
|
+
for i, line_text in enumerate(mask_code(body_lines)):
|
|
467
|
+
for pattern in SCAFFOLD_RES:
|
|
468
|
+
m = pattern.search(line_text)
|
|
469
|
+
if m:
|
|
470
|
+
flags.append(
|
|
471
|
+
f'FLAG scaffold "{m.group(0)}" (line {body_start + i}) — '
|
|
472
|
+
"drafting-context reference leaked into the doc. Rewrite it "
|
|
473
|
+
"as a real path or link."
|
|
474
|
+
)
|
|
475
|
+
|
|
476
|
+
# --- Report ---------------------------------------------------------------
|
|
477
|
+
for info in infos:
|
|
478
|
+
print(info)
|
|
479
|
+
for note in notes:
|
|
480
|
+
print(note)
|
|
481
|
+
for flag in flags:
|
|
482
|
+
print(flag)
|
|
483
|
+
summary = (
|
|
484
|
+
f"checked {checked_paths} paths, {checked_shas} SHAs, "
|
|
485
|
+
f"{checked_links} links; {len(flags)} flags"
|
|
486
|
+
)
|
|
487
|
+
if notes:
|
|
488
|
+
summary += f", {len(notes)} notes"
|
|
489
|
+
print(summary)
|
|
490
|
+
if flags:
|
|
491
|
+
return 1
|
|
492
|
+
print(f"OK: {doc_path}")
|
|
493
|
+
return 0
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
if __name__ == "__main__":
|
|
497
|
+
sys.exit(main(sys.argv))
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Validate ce-compound learning-doc frontmatter for parser-safety issues.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
python3 validate-frontmatter.py <doc-path>
|
|
6
|
+
|
|
7
|
+
Exit codes:
|
|
8
|
+
0 — frontmatter passes all checks
|
|
9
|
+
1 — validation failure (diagnostics on stderr)
|
|
10
|
+
2 — usage error (bad arguments, missing file)
|
|
11
|
+
|
|
12
|
+
Scope: this script catches *parser-safety* issues — frontmatter that strict
|
|
13
|
+
YAML parsers will silently misread. It does NOT validate against the
|
|
14
|
+
schema's required-field or enum-value rules; that's a separate concern. The
|
|
15
|
+
intent is to prevent the silent-data-loss bug class where YAML's quoting
|
|
16
|
+
rules truncate or reframe scalar values without raising.
|
|
17
|
+
|
|
18
|
+
Checks (regex-based, no YAML parser dependency):
|
|
19
|
+
1. File starts and ends frontmatter with `---` lines (matched as full
|
|
20
|
+
lines, not substrings — `----` and `---extra` are rejected)
|
|
21
|
+
2. No top-level scalar value contains ` #` unquoted (silent comment
|
|
22
|
+
truncation — what Codex caught on PR #695)
|
|
23
|
+
3. No top-level scalar value contains `: ` unquoted (mapping confusion —
|
|
24
|
+
what surfaced in a 2026-04-16 plan doc's `title:` field)
|
|
25
|
+
|
|
26
|
+
The script does NOT flag values starting with YAML reserved indicators
|
|
27
|
+
(`` ` ``, `*`, `&`, `!`, etc.) because those produce loud parser errors
|
|
28
|
+
downstream rather than silent corruption — they're already caught by
|
|
29
|
+
whatever consumes the doc. This validator's purpose is silent-corruption
|
|
30
|
+
prevention, not lint.
|
|
31
|
+
|
|
32
|
+
Pure-stdlib (no PyYAML or other third-party deps). Runs in <50ms typical.
|
|
33
|
+
Designed to produce concrete, actionable error messages so the calling
|
|
34
|
+
agent can fix and retry without ambiguity.
|
|
35
|
+
"""
|
|
36
|
+
import os
|
|
37
|
+
import re
|
|
38
|
+
import sys
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def usage_fail(msg: str) -> "NoReturn":
|
|
42
|
+
sys.stderr.write(f"validate-frontmatter: {msg}\n")
|
|
43
|
+
sys.exit(2)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def main(argv: list[str]) -> int:
|
|
47
|
+
if len(argv) != 2:
|
|
48
|
+
usage_fail(f"usage: {os.path.basename(argv[0])} <doc-path>")
|
|
49
|
+
|
|
50
|
+
doc_path = argv[1]
|
|
51
|
+
if not os.path.isfile(doc_path):
|
|
52
|
+
usage_fail(f"file not found: {doc_path}")
|
|
53
|
+
|
|
54
|
+
with open(doc_path, encoding="utf-8") as f:
|
|
55
|
+
text = f.read()
|
|
56
|
+
|
|
57
|
+
issues: list[str] = []
|
|
58
|
+
|
|
59
|
+
# Check 1: frontmatter delimiters. Match the delimiter as a complete
|
|
60
|
+
# line whose stripped content is exactly `---` — substring matching
|
|
61
|
+
# (e.g. `text.find("\n---", 4)`) would falsely accept `----` or
|
|
62
|
+
# `---extra` as a terminator and let malformed docs slip through to
|
|
63
|
+
# downstream parsers that require a strict `---` line.
|
|
64
|
+
lines = text.split("\n")
|
|
65
|
+
if not lines or lines[0].rstrip() != "---":
|
|
66
|
+
sys.stderr.write(
|
|
67
|
+
f"FAIL: {doc_path}\n"
|
|
68
|
+
f" file does not start with '---' frontmatter delimiter line\n"
|
|
69
|
+
)
|
|
70
|
+
return 1
|
|
71
|
+
|
|
72
|
+
end_idx: int | None = None
|
|
73
|
+
for i in range(1, len(lines)):
|
|
74
|
+
if lines[i].rstrip() == "---":
|
|
75
|
+
end_idx = i
|
|
76
|
+
break
|
|
77
|
+
|
|
78
|
+
if end_idx is None:
|
|
79
|
+
sys.stderr.write(
|
|
80
|
+
f"FAIL: {doc_path}\n"
|
|
81
|
+
f" frontmatter not closed (no '---' line after the opening delimiter)\n"
|
|
82
|
+
)
|
|
83
|
+
return 1
|
|
84
|
+
|
|
85
|
+
fm_text = "\n".join(lines[1:end_idx])
|
|
86
|
+
|
|
87
|
+
# Checks 2 & 3: silent-corruption quoting risks on top-level scalar
|
|
88
|
+
# fields. We scan line-by-line and only flag top-level mapping entries
|
|
89
|
+
# (no leading whitespace) whose value isn't already quoted/structured.
|
|
90
|
+
for lineno, line in enumerate(fm_text.split("\n"), start=2):
|
|
91
|
+
stripped = line.lstrip()
|
|
92
|
+
if not stripped or stripped.startswith("#"):
|
|
93
|
+
continue
|
|
94
|
+
if ":" not in line:
|
|
95
|
+
continue
|
|
96
|
+
# Top-level mapping keys only — skip nested values, array items
|
|
97
|
+
if line.startswith((" ", "\t")):
|
|
98
|
+
continue
|
|
99
|
+
# Skip pure list-marker lines like "- item" (these can't be top-level
|
|
100
|
+
# in our frontmatter convention, but be defensive)
|
|
101
|
+
if stripped.startswith("- "):
|
|
102
|
+
continue
|
|
103
|
+
|
|
104
|
+
key, _, val = line.partition(":")
|
|
105
|
+
val_stripped = val.strip()
|
|
106
|
+
if not val_stripped:
|
|
107
|
+
# Key with no value on this line — likely a parent of a nested
|
|
108
|
+
# block (`tags:` followed by `- foo`). Nothing to validate here.
|
|
109
|
+
continue
|
|
110
|
+
# Already quoted or structured (block scalar, flow collection)
|
|
111
|
+
if val_stripped[0] in '"\'[{|>':
|
|
112
|
+
continue
|
|
113
|
+
|
|
114
|
+
if re.search(r"\s#", val_stripped):
|
|
115
|
+
issues.append(
|
|
116
|
+
f"line {lineno}: '{key.strip()}' value contains ' #' — quote it. "
|
|
117
|
+
"YAML treats space-then-# as a comment delimiter and silently "
|
|
118
|
+
"drops the rest of the value."
|
|
119
|
+
)
|
|
120
|
+
if re.search(r":\s", val_stripped):
|
|
121
|
+
issues.append(
|
|
122
|
+
f"line {lineno}: '{key.strip()}' value contains ': ' — quote it. "
|
|
123
|
+
"Strict YAML parsers may treat this as a nested mapping."
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
if issues:
|
|
127
|
+
sys.stderr.write(f"FAIL: {doc_path}\n")
|
|
128
|
+
for issue in issues:
|
|
129
|
+
sys.stderr.write(f" {issue}\n")
|
|
130
|
+
return 1
|
|
131
|
+
|
|
132
|
+
print(f"OK: {doc_path}")
|
|
133
|
+
return 0
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
if __name__ == "__main__":
|
|
137
|
+
sys.exit(main(sys.argv))
|