ergane-cli 0.6.0__tar.gz → 0.7.0__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.
- ergane_cli-0.7.0/.agents/skills/refine-spec/SKILL.md +107 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/accepted-replacement/plan.md +30 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/accepted-replacement/spec.md +25 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/accepted-replacement/tasks.md +5 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/independent-files/plan.md +45 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/independent-files/spec.md +37 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/independent-files/tasks.md +9 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/integration-owner/plan.md +50 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/integration-owner/spec.md +37 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/integration-owner/tasks.md +9 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/shared-decision-write/plan.md +50 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/shared-decision-write/spec.md +37 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/shared-decision-write/tasks.md +9 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/stale-reference/plan.md +29 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/stale-reference/spec.md +25 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/stale-reference/tasks.md +5 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/unresolved-intent/plan.md +29 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/unresolved-intent/spec.md +25 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/fixtures/unresolved-intent/tasks.md +5 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/references/capability-evidence.md +10 -0
- ergane_cli-0.7.0/.agents/skills/refine-spec/references/review-record.md +50 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/SKILL.md +107 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/accepted-replacement/plan.md +30 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/accepted-replacement/spec.md +25 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/accepted-replacement/tasks.md +5 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/independent-files/plan.md +45 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/independent-files/spec.md +37 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/independent-files/tasks.md +9 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/integration-owner/plan.md +50 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/integration-owner/spec.md +37 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/integration-owner/tasks.md +9 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/shared-decision-write/plan.md +50 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/shared-decision-write/spec.md +37 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/shared-decision-write/tasks.md +9 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/stale-reference/plan.md +29 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/stale-reference/spec.md +25 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/stale-reference/tasks.md +5 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/unresolved-intent/plan.md +29 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/unresolved-intent/spec.md +25 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/fixtures/unresolved-intent/tasks.md +5 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/references/capability-evidence.md +10 -0
- ergane_cli-0.7.0/.claude/skills/refine-spec/references/review-record.md +50 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.gitignore +1 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/PKG-INFO +4 -4
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/README.md +3 -3
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/activities/agent_activities.py +144 -22
- ergane_cli-0.7.0/factory/activities/observability_activities.py +285 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/activities/roadmap_activities.py +16 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/activities/verify_activities.py +586 -2
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/attestation/__init__.py +4 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/attestation/archive.py +47 -2
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/attestation/journal.py +204 -2
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/attestation/models.py +2 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/attestation/usage.py +8 -0
- ergane_cli-0.7.0/factory/cli/check.py +150 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/doctor.py +6 -1
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/attestation.py +12 -1
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/build.py +142 -43
- ergane_cli-0.7.0/factory/cli/nouns/check.py +13 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/skills.py +11 -15
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/config.py +33 -1
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/controlplane/config.py +29 -1
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/doctor/cli.py +6 -1
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/env.py +5 -2
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/mergequeue/gh.py +22 -2
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/mergequeue/github_forge.py +35 -10
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/mergequeue/models.py +12 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/mergequeue/onboard.py +6 -2
- ergane_cli-0.7.0/factory/observability/__init__.py +17 -0
- ergane_cli-0.7.0/factory/observability/bundle.py +508 -0
- ergane_cli-0.7.0/factory/operator/__init__.py +2 -0
- ergane_cli-0.7.0/factory/operator/brief.py +179 -0
- ergane_cli-0.7.0/factory/operator/context_models.py +197 -0
- ergane_cli-0.7.0/factory/operator/context_store.py +741 -0
- ergane_cli-0.7.0/factory/operator/memory.py +669 -0
- ergane_cli-0.7.0/factory/operator/memory_sync.py +444 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/roadmap/models.py +132 -5
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/roadmap/workflow.py +28 -1
- ergane_cli-0.7.0/factory/sandbox_scratch.py +231 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/spec/composition.py +21 -1
- ergane_cli-0.7.0/factory/spec/refinement.py +618 -0
- ergane_cli-0.7.0/factory/supervision/action_journal.py +472 -0
- ergane_cli-0.7.0/factory/supervision/actions.py +98 -0
- ergane_cli-0.7.0/factory/supervision/batch_models.py +459 -0
- ergane_cli-0.7.0/factory/supervision/batch_store.py +602 -0
- ergane_cli-0.7.0/factory/supervision/readiness_checks.py +395 -0
- ergane_cli-0.7.0/factory/supervision/readiness_receipt.py +684 -0
- ergane_cli-0.7.0/factory/supervision/runtime_bindings.py +187 -0
- ergane_cli-0.7.0/factory/supervision/watch.py +851 -0
- ergane_cli-0.7.0/factory/supervision/watch_activities.py +118 -0
- ergane_cli-0.7.0/factory/supervision/worker_readiness.py +463 -0
- ergane_cli-0.7.0/factory/verify/codex_judge.py +244 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/diffbounds.py +25 -4
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/diffcheck.py +5 -3
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/factory_yaml.py +307 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/gates.py +73 -66
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/judge.py +61 -24
- ergane_cli-0.7.0/factory/verify/judge_transport.py +27 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/models.py +102 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/toolchain.py +36 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/worker.py +48 -4
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/adapter.py +151 -32
- ergane_cli-0.7.0/factory/workgraph/builder_allowance.py +287 -0
- ergane_cli-0.7.0/factory/workgraph/builder_credentials.py +121 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/cli.py +86 -10
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/codex_credential.py +31 -13
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/codex_events.py +17 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/confinement.py +8 -1
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/delta.py +3 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/models.py +84 -1
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/preflight.py +37 -1
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/prompt.py +40 -7
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/workflow.py +1005 -145
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/worktree.py +142 -50
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/pyproject.toml +6 -1
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/away-mode/SKILL.md +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/build-metrics/SKILL.md +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/build-metrics/reference/baseline-2026-08-19.md +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/build-metrics/reference/current-baseline.md +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/build-metrics/scripts/commit_sizes.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/build-metrics/scripts/loc.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/build-metrics/scripts/rework.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/escalation-triage/SKILL.md +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/escalation-triage/escalation_render.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/escalation-triage/fixtures/escalation.json +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/findings-ingest/SKILL.md +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/floor-status/SKILL.md +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/floor-status/fixtures/attempts.json +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/floor-status/fixtures/services.json +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/floor-status/fixtures/status.json +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/floor-status/fixtures/transcript.txt +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/floor-status/floor_render.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/spec-html/SKILL.md +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.agents/skills/spec-html/render.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/away-mode/SKILL.md +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/build-metrics/SKILL.md +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/build-metrics/reference/baseline-2026-08-19.md +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/build-metrics/reference/current-baseline.md +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/build-metrics/scripts/commit_sizes.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/build-metrics/scripts/loc.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/build-metrics/scripts/rework.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/escalation-triage/SKILL.md +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/escalation-triage/escalation_render.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/escalation-triage/fixtures/escalation.json +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/findings-ingest/SKILL.md +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/floor-status/SKILL.md +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/floor-status/fixtures/attempts.json +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/floor-status/fixtures/services.json +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/floor-status/fixtures/status.json +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/floor-status/fixtures/transcript.txt +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/floor-status/floor_render.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/spec-html/SKILL.md +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/.claude/skills/spec-html/render.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/LICENSE +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/NOTICE +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/container/compose.demo.yaml +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/container/compose.reference.yaml +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/container/ergane-bwrap.apparmor +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/container/ergane-engine.profile +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/container/ergane-install-answer.demo.toml +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/container/gateway-config.yaml +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/container/personas.demo.yaml +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/container/seccomp-ergane.json +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/default_floor.md +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/__init__.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/activities/__init__.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/activities/attestation_activities.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/activities/merge_activities.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/activities/notify_activities.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/activities/usage_activities.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/attestation/attachments.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/attestation/report.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/attestation/rollup.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/__init__.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/completion.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/env.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/errors.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/init.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/install.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/landing.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/main.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/__init__.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/answer.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/completion.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/doctor.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/engine.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/env.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/escalations.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/findings.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/init.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/install.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/repo.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/roadmap.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/skills.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/spec.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/status.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/uninstall.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/usage.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/nouns/worker.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/promotion.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/repo.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/repo_export.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/roadmap.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/status.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/uninstall.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/cli/usage.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/constitution.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/controlplane/__init__.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/controlplane/canary/__init__.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/controlplane/canary/diff.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/controlplane/canary/probe.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/controlplane/resolve.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/controlplane/verify.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/discovery/__init__.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/discovery/llm_enrichment.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/discovery/llm_scanner.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/discovery/proposal.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/doctor/__init__.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/doctor/models.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/doctor/probes.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/doctor/scaffold.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/doctor/store.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/doctor/triage.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/escalation/__init__.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/escalation/client.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/escalation/question.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/escalation/workflow.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/locking.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/mergequeue/__init__.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/mergequeue/classify.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/mergequeue/forge.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/mergequeue/governance.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/mergequeue/merge_queue_ruleset.json +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/mergequeue/messages.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/mergequeue/rejection.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/mergequeue/reset.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/mergequeue/wiring.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/notify/__init__.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/notify/adapter.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/notify/messages.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/notify/null_adapter.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/notify/redact.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/notify/service.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/notify/webhook.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/registry.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/roadmap/__init__.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/roadmap/cli.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/roadmap/discovery.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/roadmap/schedule.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/spec/__init__.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/spec/anchors.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/spec/evidence.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/spec/layers.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/spec/report.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/stack_packs/agnostic.yaml +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/stack_packs/node.yaml +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/stack_packs/python.yaml +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/stack_packs.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/supervision/__init__.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/supervision/alert.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/supervision/container_engine.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/supervision/container_manifest.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/supervision/container_profile.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/supervision/container_project.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/supervision/container_supervisor.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/supervision/demo_driver.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/supervision/deploy.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/supervision/engine_identity.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/supervision/engine_upgrade.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/supervision/probe.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/supervision/temporal_server.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/supervision/units.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/usage/__init__.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/usage/aggregate.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/usage/cli.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/usage/codex_evidence.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/usage/ledger.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/usage/litellm_client.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/usage/models.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/usage/reconcile.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/usage/runner.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/__init__.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/artifact_capture.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/criteria.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/gate_annotation.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/git_evidence.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/ladder.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/question.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/remediation.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/sandbox_remedy.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/store.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/verify/worktree_snapshot.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/versioning.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/__init__.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/contention.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/credential_status.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/derive.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/detector.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/governance.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/landed.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/factory/workgraph/qualification.py +0 -0
- {ergane_cli-0.6.0 → ergane_cli-0.7.0}/personas.example.yaml +0 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "refine-spec"
|
|
3
|
+
description: "Reconcile a Spec Kit trio with current source, tests, accepted decisions and capability evidence, then emit one bounded Refinement Record and a real validator report. Stops at review boundaries; it does not implement, transition readiness, answer escalations, or dispatch."
|
|
4
|
+
compatibility: "Requires the ergane CLI and an operator-declared target repository plus specs root"
|
|
5
|
+
metadata:
|
|
6
|
+
author: "operator session, 2026-09-21"
|
|
7
|
+
status: "canonical refinement review procedure"
|
|
8
|
+
user-invocable: true
|
|
9
|
+
disable-model-invocation: false
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Refine a specification
|
|
13
|
+
|
|
14
|
+
## Establish the declared roots
|
|
15
|
+
|
|
16
|
+
Read all three: `spec.md`, `plan.md`, and `tasks.md`. Before evidence work,
|
|
17
|
+
resolve the target declaration, not a checkout guess:
|
|
18
|
+
|
|
19
|
+
1. Read `ergane.yaml` in the operator-declared target repository.
|
|
20
|
+
2. Read `factory.yaml` in the same target when it is the runtime/gate
|
|
21
|
+
declaration. `ergane.yaml` is the manifest name in new text; honor the
|
|
22
|
+
resolver's legacy `factory.yaml` compatibility when that is what the target
|
|
23
|
+
provides.
|
|
24
|
+
3. Set `TARGET_REPO` and `SPECS_ROOT` explicitly. Never infer either from the
|
|
25
|
+
current working directory, checked-out branch, or inherited environment.
|
|
26
|
+
|
|
27
|
+
## Reconcile current evidence
|
|
28
|
+
|
|
29
|
+
Read the relevant current behavior, current tests, domain vocabulary, accepted
|
|
30
|
+
decision sources, and task slices. A factual answer is traceable to a current
|
|
31
|
+
file, command output, or landed decision. An unresolved product choice is
|
|
32
|
+
different: do not infer it from history, remembered preferences, or authority.
|
|
33
|
+
Expose it as a concrete question in `open_questions`, and let the validator
|
|
34
|
+
block readiness.
|
|
35
|
+
|
|
36
|
+
Recall available cross-session memory. Write every applicable lesson into the
|
|
37
|
+
plan as a named plan trap, with its mechanism and the check that prevents a
|
|
38
|
+
repeat. Do not turn a lesson into approval, implementation, or dispatch.
|
|
39
|
+
|
|
40
|
+
## Write tests and preserved behavior
|
|
41
|
+
|
|
42
|
+
For every story, list concrete test files and assertions. An existing test
|
|
43
|
+
preserved by the story must state the invariant it still proves. A replacement
|
|
44
|
+
must state the replacement assertion and cite a nonempty accepted decision.
|
|
45
|
+
A new test pairs with `add`; an existing test pairs with `preserve` or
|
|
46
|
+
`replace`. Never delete a test merely because it conflicts with a proposed
|
|
47
|
+
behavior. Preserve quality and the applicable selector, renderer, lifecycle,
|
|
48
|
+
timeout, credential-exclusion, and no-residue checks. If a gate timed out,
|
|
49
|
+
preserve both the earlier failed assertions and the timeout fact.
|
|
50
|
+
|
|
51
|
+
## Separate checks by boundary
|
|
52
|
+
|
|
53
|
+
The record separates development, handoff, independent verification, and
|
|
54
|
+
release qualification:
|
|
55
|
+
|
|
56
|
+
- `checks.development` contains focused commands useful while editing.
|
|
57
|
+
- `checks.handoff` is the literal `declared_gates`; no development subset is
|
|
58
|
+
the handoff boundary.
|
|
59
|
+
- `checks.independent` is the literal `declared_pipeline`; no local run is the
|
|
60
|
+
independent boundary.
|
|
61
|
+
- `checks.release` names the applicable release requirements and evidence
|
|
62
|
+
owner. Selector/renderer/lifecycle checks remain in release if they apply.
|
|
63
|
+
|
|
64
|
+
A green run is evidence, not the verdict. Rerun a relevant check after the
|
|
65
|
+
code, tests, spec, plan, tasks, or skill changes or after a failure.
|
|
66
|
+
|
|
67
|
+
## Derive ownership from the actual task text
|
|
68
|
+
|
|
69
|
+
Use actual task text, not a paraphrase, when classifying writes. Inspect the
|
|
70
|
+
actual derived graph, including inferred edges. For a shared write, use the
|
|
71
|
+
existing merge edge or declare the matching ownership; do not remove a path
|
|
72
|
+
from tasks to hide contention. For append-only decision logs, name one
|
|
73
|
+
integration writer, preserve landed entries byte-for-byte, and compare candidate
|
|
74
|
+
epics in the release DAG: an intra-epic graph says nothing about another epic's
|
|
75
|
+
writers. Cross-spec concurrency is advisory only.
|
|
76
|
+
|
|
77
|
+
## Use capability evidence honestly
|
|
78
|
+
|
|
79
|
+
Keep declared, available, and executed capabilities distinct. Declared skill
|
|
80
|
+
metadata, filesystem availability, a fixture replay, and observed client
|
|
81
|
+
follow-through are not the same fact. Use the capability table in
|
|
82
|
+
`references/capability-evidence.md`; do not claim execution that did not occur.
|
|
83
|
+
|
|
84
|
+
Read one unchanged version per working context. Refresh the read when skill
|
|
85
|
+
changes, a newer version appears, or the client loses that context.
|
|
86
|
+
|
|
87
|
+
## Complete the review
|
|
88
|
+
|
|
89
|
+
Fill the format in `references/review-record.md`, then run:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
uv run ergane spec validate "$SPEC_DIR" \
|
|
93
|
+
--target-repo "$TARGET_REPO" \
|
|
94
|
+
--specs-root "$SPECS_ROOT" \
|
|
95
|
+
--json
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Do not execute review command strings from the record. End with a review record
|
|
99
|
+
plus the exact validator report. Preserve missing-target, missing-corpus,
|
|
100
|
+
legacy-absence, and skipped states; exit status alone is not release readiness.
|
|
101
|
+
|
|
102
|
+
## Authority boundary
|
|
103
|
+
|
|
104
|
+
This skill reviews; it does not implement, transition readiness, or answer
|
|
105
|
+
escalations. It does not grant implementation, readiness, or operational
|
|
106
|
+
authority. It does not dispatch an attempt. It adds no approval for already
|
|
107
|
+
authorized refinement.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Plan
|
|
2
|
+
|
|
3
|
+
## Refinement Record
|
|
4
|
+
|
|
5
|
+
```yaml
|
|
6
|
+
version: 1
|
|
7
|
+
reviewed_revision: HEAD
|
|
8
|
+
stories:
|
|
9
|
+
US1:
|
|
10
|
+
tests:
|
|
11
|
+
- path: tests/test_example.py
|
|
12
|
+
status: existing
|
|
13
|
+
disposition: replace
|
|
14
|
+
assertion: the replacement behavior is asserted
|
|
15
|
+
decision: spec.md:FR-001
|
|
16
|
+
preserved_behavior:
|
|
17
|
+
- the prior decision citation and decision identity are preserved
|
|
18
|
+
checks:
|
|
19
|
+
development:
|
|
20
|
+
- uv run pytest tests/test_example.py
|
|
21
|
+
handoff: declared_gates
|
|
22
|
+
independent: declared_pipeline
|
|
23
|
+
release: ['release owner: docs/decisions.md']
|
|
24
|
+
writes:
|
|
25
|
+
- factory/behavior.py
|
|
26
|
+
- tests/test_example.py
|
|
27
|
+
no_write_reason: ""
|
|
28
|
+
shared_writes: []
|
|
29
|
+
open_questions: []
|
|
30
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
state: draft
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Feature Specification: Accepted replacement fixture
|
|
6
|
+
|
|
7
|
+
## Requirements *(mandatory)*
|
|
8
|
+
|
|
9
|
+
- **FR-001**: The accepted behavior MUST replace the current example.
|
|
10
|
+
|
|
11
|
+
### User Story 1 - Accepted replacement (Priority: P1)
|
|
12
|
+
|
|
13
|
+
As the operator, I want the accepted behavior to replace the current example.
|
|
14
|
+
|
|
15
|
+
**Acceptance Scenarios**:
|
|
16
|
+
|
|
17
|
+
1. **Given** the accepted decision, **When** the example runs, **Then** it asserts the replacement behavior.
|
|
18
|
+
|
|
19
|
+
## Work Graph
|
|
20
|
+
|
|
21
|
+
```yaml
|
|
22
|
+
US1:
|
|
23
|
+
depends_on: []
|
|
24
|
+
implements: [FR-001]
|
|
25
|
+
```
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Plan
|
|
2
|
+
|
|
3
|
+
## Refinement Record
|
|
4
|
+
|
|
5
|
+
```yaml
|
|
6
|
+
version: 1
|
|
7
|
+
reviewed_revision: HEAD
|
|
8
|
+
stories:
|
|
9
|
+
US1:
|
|
10
|
+
tests:
|
|
11
|
+
- path: tests/test_first.py
|
|
12
|
+
status: existing
|
|
13
|
+
disposition: preserve
|
|
14
|
+
assertion: the first bounded behavior remains covered
|
|
15
|
+
decision: spec.md:FR-001
|
|
16
|
+
preserved_behavior:
|
|
17
|
+
- the first behavior remains deterministic
|
|
18
|
+
checks:
|
|
19
|
+
development: ['uv run pytest tests/test_first.py']
|
|
20
|
+
handoff: declared_gates
|
|
21
|
+
independent: declared_pipeline
|
|
22
|
+
release: ['release owner: docs/decisions.md']
|
|
23
|
+
writes: [factory/first.py]
|
|
24
|
+
no_write_reason: ""
|
|
25
|
+
shared_writes: []
|
|
26
|
+
open_questions: []
|
|
27
|
+
US2:
|
|
28
|
+
tests:
|
|
29
|
+
- path: tests/test_second.py
|
|
30
|
+
status: existing
|
|
31
|
+
disposition: preserve
|
|
32
|
+
assertion: the second bounded behavior remains covered
|
|
33
|
+
decision: spec.md:FR-002
|
|
34
|
+
preserved_behavior:
|
|
35
|
+
- the second behavior remains deterministic
|
|
36
|
+
checks:
|
|
37
|
+
development: ['uv run pytest tests/test_second.py']
|
|
38
|
+
handoff: declared_gates
|
|
39
|
+
independent: declared_pipeline
|
|
40
|
+
release: ['release owner: docs/decisions.md']
|
|
41
|
+
writes: [factory/second.py]
|
|
42
|
+
no_write_reason: ""
|
|
43
|
+
shared_writes: []
|
|
44
|
+
open_questions: []
|
|
45
|
+
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
state: draft
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Feature Specification: Independent writers fixture
|
|
6
|
+
|
|
7
|
+
## Requirements *(mandatory)*
|
|
8
|
+
|
|
9
|
+
- **FR-001**: The first story MUST write only its file.
|
|
10
|
+
- **FR-002**: The second story MUST write only its own file.
|
|
11
|
+
|
|
12
|
+
### User Story 1 - First writer (Priority: P1)
|
|
13
|
+
|
|
14
|
+
As the operator, I want bounded parallel work.
|
|
15
|
+
|
|
16
|
+
**Acceptance Scenarios**:
|
|
17
|
+
|
|
18
|
+
1. **Given** unrelated files, **When** the stories run, **Then** parallelism remains available.
|
|
19
|
+
|
|
20
|
+
### User Story 2 - Second writer (Priority: P1)
|
|
21
|
+
|
|
22
|
+
As the operator, I want an unrelated bounded slice.
|
|
23
|
+
|
|
24
|
+
**Acceptance Scenarios**:
|
|
25
|
+
|
|
26
|
+
1. **Given** no common file, **When** the stories run, **Then** no contention edge is needed.
|
|
27
|
+
|
|
28
|
+
## Work Graph
|
|
29
|
+
|
|
30
|
+
```yaml
|
|
31
|
+
US1:
|
|
32
|
+
depends_on: []
|
|
33
|
+
implements: [FR-001]
|
|
34
|
+
US2:
|
|
35
|
+
depends_on: []
|
|
36
|
+
implements: [FR-002]
|
|
37
|
+
```
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Plan
|
|
2
|
+
|
|
3
|
+
## Refinement Record
|
|
4
|
+
|
|
5
|
+
```yaml
|
|
6
|
+
version: 1
|
|
7
|
+
reviewed_revision: HEAD
|
|
8
|
+
stories:
|
|
9
|
+
US1:
|
|
10
|
+
tests:
|
|
11
|
+
- path: tests/test_decisions.py
|
|
12
|
+
status: existing
|
|
13
|
+
disposition: preserve
|
|
14
|
+
assertion: old entries remain byte-for-byte
|
|
15
|
+
decision: spec.md:FR-001
|
|
16
|
+
preserved_behavior:
|
|
17
|
+
- landed decision entries remain byte-for-byte
|
|
18
|
+
checks:
|
|
19
|
+
development: ['uv run pytest tests/test_decisions.py']
|
|
20
|
+
handoff: declared_gates
|
|
21
|
+
independent: declared_pipeline
|
|
22
|
+
release: ['release owner: docs/decisions.md']
|
|
23
|
+
writes: [docs/decisions.md, factory/decision.py]
|
|
24
|
+
no_write_reason: ""
|
|
25
|
+
shared_writes:
|
|
26
|
+
- path: docs/decisions.md
|
|
27
|
+
other_spec: 001-refinement
|
|
28
|
+
other_story: US2
|
|
29
|
+
disposition: integration_owner
|
|
30
|
+
reason: US2 supplies a distinct input and does not write the shared log
|
|
31
|
+
open_questions: []
|
|
32
|
+
US2:
|
|
33
|
+
tests:
|
|
34
|
+
- path: tests/test_decisions.py
|
|
35
|
+
status: existing
|
|
36
|
+
disposition: preserve
|
|
37
|
+
assertion: the input remains covered
|
|
38
|
+
decision: spec.md:FR-002
|
|
39
|
+
preserved_behavior:
|
|
40
|
+
- the input remains bounded and deterministic
|
|
41
|
+
checks:
|
|
42
|
+
development: ['uv run pytest tests/test_decisions.py']
|
|
43
|
+
handoff: declared_gates
|
|
44
|
+
independent: declared_pipeline
|
|
45
|
+
release: ['release owner: docs/decisions.md']
|
|
46
|
+
writes: [factory/integration-input.py]
|
|
47
|
+
no_write_reason: ""
|
|
48
|
+
shared_writes: []
|
|
49
|
+
open_questions: []
|
|
50
|
+
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
state: draft
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Feature Specification: Integration owner fixture
|
|
6
|
+
|
|
7
|
+
## Requirements *(mandatory)*
|
|
8
|
+
|
|
9
|
+
- **FR-001**: The integration writer MUST be the single final writer.
|
|
10
|
+
- **FR-002**: The other story MUST provide a distinct integration input.
|
|
11
|
+
|
|
12
|
+
### User Story 1 - Integration owner (Priority: P1)
|
|
13
|
+
|
|
14
|
+
As the operator, I want exactly one final decision writer.
|
|
15
|
+
|
|
16
|
+
**Acceptance Scenarios**:
|
|
17
|
+
|
|
18
|
+
1. **Given** a distinct input, **When** story 1 runs, **Then** it preserves the immutable log.
|
|
19
|
+
|
|
20
|
+
### User Story 2 - Integration input (Priority: P1)
|
|
21
|
+
|
|
22
|
+
As the operator, I want a separate bounded input.
|
|
23
|
+
|
|
24
|
+
**Acceptance Scenarios**:
|
|
25
|
+
|
|
26
|
+
1. **Given** the decision log, **When** story 2 runs, **Then** it writes only its input file.
|
|
27
|
+
|
|
28
|
+
## Work Graph
|
|
29
|
+
|
|
30
|
+
```yaml
|
|
31
|
+
US1:
|
|
32
|
+
depends_on: []
|
|
33
|
+
implements: [FR-001]
|
|
34
|
+
US2:
|
|
35
|
+
depends_on: []
|
|
36
|
+
implements: [FR-002]
|
|
37
|
+
```
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Plan
|
|
2
|
+
|
|
3
|
+
## Refinement Record
|
|
4
|
+
|
|
5
|
+
```yaml
|
|
6
|
+
version: 1
|
|
7
|
+
reviewed_revision: HEAD
|
|
8
|
+
stories:
|
|
9
|
+
US1:
|
|
10
|
+
tests:
|
|
11
|
+
- path: tests/test_decisions.py
|
|
12
|
+
status: existing
|
|
13
|
+
disposition: preserve
|
|
14
|
+
assertion: the input remains covered
|
|
15
|
+
decision: spec.md:FR-001
|
|
16
|
+
preserved_behavior:
|
|
17
|
+
- the bounded decision input remains deterministic
|
|
18
|
+
checks:
|
|
19
|
+
development: ['uv run pytest tests/test_decisions.py']
|
|
20
|
+
handoff: declared_gates
|
|
21
|
+
independent: declared_pipeline
|
|
22
|
+
release: ['release owner: docs/decisions.md']
|
|
23
|
+
writes: [docs/decisions.md, factory/decision.py]
|
|
24
|
+
no_write_reason: ""
|
|
25
|
+
shared_writes:
|
|
26
|
+
- path: docs/decisions.md
|
|
27
|
+
other_spec: 001-refinement
|
|
28
|
+
other_story: US2
|
|
29
|
+
disposition: merge_order
|
|
30
|
+
reason: the derived edge lands US1 before US2
|
|
31
|
+
open_questions: []
|
|
32
|
+
US2:
|
|
33
|
+
tests:
|
|
34
|
+
- path: tests/test_decisions.py
|
|
35
|
+
status: existing
|
|
36
|
+
disposition: preserve
|
|
37
|
+
assertion: old decision entries remain byte-for-byte
|
|
38
|
+
decision: spec.md:FR-002
|
|
39
|
+
preserved_behavior:
|
|
40
|
+
- landed entries in docs/decisions.md remain byte-for-byte
|
|
41
|
+
checks:
|
|
42
|
+
development: ['uv run pytest tests/test_decisions.py']
|
|
43
|
+
handoff: declared_gates
|
|
44
|
+
independent: declared_pipeline
|
|
45
|
+
release: ['release owner: docs/decisions.md']
|
|
46
|
+
writes: [docs/decisions.md]
|
|
47
|
+
no_write_reason: ""
|
|
48
|
+
shared_writes: []
|
|
49
|
+
open_questions: []
|
|
50
|
+
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
state: draft
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Feature Specification: Shared decision write fixture
|
|
6
|
+
|
|
7
|
+
## Requirements *(mandatory)*
|
|
8
|
+
|
|
9
|
+
- **FR-001**: The first story MUST prepare the accepted decision.
|
|
10
|
+
- **FR-002**: The second story MUST append without changing landed entries.
|
|
11
|
+
|
|
12
|
+
### User Story 1 - Decision input (Priority: P1)
|
|
13
|
+
|
|
14
|
+
As the operator, I want a bounded decision input.
|
|
15
|
+
|
|
16
|
+
**Acceptance Scenarios**:
|
|
17
|
+
|
|
18
|
+
1. **Given** the decision source, **When** story 1 runs, **Then** it provides the integration input.
|
|
19
|
+
|
|
20
|
+
### User Story 2 - Decision append (Priority: P1)
|
|
21
|
+
|
|
22
|
+
As the operator, I want one append-only integration writer.
|
|
23
|
+
|
|
24
|
+
**Acceptance Scenarios**:
|
|
25
|
+
|
|
26
|
+
1. **Given** story 1 is merged, **When** story 2 runs, **Then** it preserves landed entries byte-for-byte.
|
|
27
|
+
|
|
28
|
+
## Work Graph
|
|
29
|
+
|
|
30
|
+
```yaml
|
|
31
|
+
US1:
|
|
32
|
+
depends_on: []
|
|
33
|
+
implements: [FR-001]
|
|
34
|
+
US2:
|
|
35
|
+
depends_on: []
|
|
36
|
+
implements: [FR-002]
|
|
37
|
+
```
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Tasks
|
|
2
|
+
|
|
3
|
+
## Phase 1: User Story 1
|
|
4
|
+
|
|
5
|
+
- [ ] T001 [US1-S1] Add `factory/decision.py` input and append its source citation to `docs/decisions.md`.
|
|
6
|
+
|
|
7
|
+
## Phase 2: User Story 2
|
|
8
|
+
|
|
9
|
+
- [ ] T002 [US2-S1] Append the accepted decision to `docs/decisions.md`; preserve landed entries byte-for-byte.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Plan
|
|
2
|
+
|
|
3
|
+
## Refinement Record
|
|
4
|
+
|
|
5
|
+
```yaml
|
|
6
|
+
version: 1
|
|
7
|
+
reviewed_revision: HEAD
|
|
8
|
+
stories:
|
|
9
|
+
US1:
|
|
10
|
+
tests:
|
|
11
|
+
- path: tests/missing.py
|
|
12
|
+
status: existing
|
|
13
|
+
disposition: preserve
|
|
14
|
+
assertion: the referenced behavior remains covered
|
|
15
|
+
decision: spec.md:FR-001
|
|
16
|
+
preserved_behavior:
|
|
17
|
+
- the referenced behavior remains covered
|
|
18
|
+
checks:
|
|
19
|
+
development:
|
|
20
|
+
- uv run pytest tests/missing.py
|
|
21
|
+
handoff: declared_gates
|
|
22
|
+
independent: declared_pipeline
|
|
23
|
+
release: ['release owner: docs/decisions.md']
|
|
24
|
+
writes:
|
|
25
|
+
- factory/behavior.py
|
|
26
|
+
no_write_reason: ""
|
|
27
|
+
shared_writes: []
|
|
28
|
+
open_questions: []
|
|
29
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
state: draft
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Feature Specification: Stale reference fixture
|
|
6
|
+
|
|
7
|
+
## Requirements *(mandatory)*
|
|
8
|
+
|
|
9
|
+
- **FR-001**: A stale test reference MUST be refused.
|
|
10
|
+
|
|
11
|
+
### User Story 1 - Stale reference (Priority: P1)
|
|
12
|
+
|
|
13
|
+
As the operator, I want stale references to fail by name.
|
|
14
|
+
|
|
15
|
+
**Acceptance Scenarios**:
|
|
16
|
+
|
|
17
|
+
1. **Given** a missing referenced test, **When** validation runs, **Then** it refuses the reference.
|
|
18
|
+
|
|
19
|
+
## Work Graph
|
|
20
|
+
|
|
21
|
+
```yaml
|
|
22
|
+
US1:
|
|
23
|
+
depends_on: []
|
|
24
|
+
implements: [FR-001]
|
|
25
|
+
```
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Plan
|
|
2
|
+
|
|
3
|
+
## Refinement Record
|
|
4
|
+
|
|
5
|
+
```yaml
|
|
6
|
+
version: 1
|
|
7
|
+
reviewed_revision: HEAD
|
|
8
|
+
stories:
|
|
9
|
+
US1:
|
|
10
|
+
tests:
|
|
11
|
+
- path: tests/test_example.py
|
|
12
|
+
status: existing
|
|
13
|
+
disposition: preserve
|
|
14
|
+
assertion: the current behavior remains observable
|
|
15
|
+
decision: spec.md:FR-001
|
|
16
|
+
preserved_behavior:
|
|
17
|
+
- the current test remains unchanged
|
|
18
|
+
checks:
|
|
19
|
+
development:
|
|
20
|
+
- uv run pytest tests/test_example.py
|
|
21
|
+
handoff: declared_gates
|
|
22
|
+
independent: declared_pipeline
|
|
23
|
+
release: ['release owner: docs/decisions.md']
|
|
24
|
+
writes: []
|
|
25
|
+
no_write_reason: no product choice is accepted
|
|
26
|
+
shared_writes: []
|
|
27
|
+
open_questions:
|
|
28
|
+
- Which product behavior wins?
|
|
29
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
state: draft
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Feature Specification: Unresolved intent fixture
|
|
6
|
+
|
|
7
|
+
## Requirements *(mandatory)*
|
|
8
|
+
|
|
9
|
+
- **FR-001**: The product choice MUST be exposed before implementation.
|
|
10
|
+
|
|
11
|
+
### User Story 1 - Unresolved intent (Priority: P1)
|
|
12
|
+
|
|
13
|
+
As the operator, I want an unresolved product choice to block readiness.
|
|
14
|
+
|
|
15
|
+
**Acceptance Scenarios**:
|
|
16
|
+
|
|
17
|
+
1. **Given** no accepted decision, **When** refinement runs, **Then** it asks the named product question.
|
|
18
|
+
|
|
19
|
+
## Work Graph
|
|
20
|
+
|
|
21
|
+
```yaml
|
|
22
|
+
US1:
|
|
23
|
+
depends_on: []
|
|
24
|
+
implements: [FR-001]
|
|
25
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Capability evidence
|
|
2
|
+
|
|
3
|
+
| Capability | Declared | Available | Executed | Evidence |
|
|
4
|
+
| --- | --- | --- | --- | --- |
|
|
5
|
+
| Skill instruction | Yes | Yes | Not observed | SKILL.md |
|
|
6
|
+
| Skill fixture replay | No | Yes | Yes | deterministic validator report |
|
|
7
|
+
| Client follow-through | No | Unknown | No | authorized release trial |
|
|
8
|
+
|
|
9
|
+
Do not promote a fixture replay to agent compliance. The release trial must
|
|
10
|
+
observe the authorized client, and the report must say whether it did.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Review record format
|
|
2
|
+
|
|
3
|
+
Place exactly one `## Refinement Record` section and exactly one YAML fence in
|
|
4
|
+
the plan. Version 1 has only `version: 1`, `reviewed_revision`, and
|
|
5
|
+
`stories`. `reviewed_revision` is a revision that resolves locally in the
|
|
6
|
+
declared target; a later revision is a review input, not proof of identity.
|
|
7
|
+
`stories` keys exactly match the declared stories. The validator checks
|
|
8
|
+
structure and references, not the semantic truth of assertions or the authority
|
|
9
|
+
of citations.
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
version: 1
|
|
13
|
+
reviewed_revision: HEAD
|
|
14
|
+
stories:
|
|
15
|
+
US1:
|
|
16
|
+
tests:
|
|
17
|
+
- path: tests/example.py
|
|
18
|
+
status: existing
|
|
19
|
+
disposition: replace
|
|
20
|
+
assertion: the accepted replacement behavior is asserted
|
|
21
|
+
decision: spec.md:FR-001
|
|
22
|
+
preserved_behavior:
|
|
23
|
+
- the previous decision source and landed entries remain identified
|
|
24
|
+
checks:
|
|
25
|
+
development:
|
|
26
|
+
- uv run pytest tests/example.py
|
|
27
|
+
handoff: declared_gates
|
|
28
|
+
independent: declared_pipeline
|
|
29
|
+
release:
|
|
30
|
+
- 'release owner: docs/decisions.md'
|
|
31
|
+
writes:
|
|
32
|
+
- factory/example.py
|
|
33
|
+
no_write_reason: ""
|
|
34
|
+
shared_writes: []
|
|
35
|
+
open_questions: []
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
For replacement, the decision is a source citation, the assertion names the
|
|
39
|
+
replacement behavior, and `preserved_behavior` names the behavior, citation, or
|
|
40
|
+
landed bytes that must remain. Empty tests require a nonempty
|
|
41
|
+
`no_test_change_reason`; empty writes require a nonempty `no_write_reason`.
|
|
42
|
+
An unresolved product choice goes in `open_questions` and blocks readiness
|
|
43
|
+
instead of being settled by preference.
|
|
44
|
+
|
|
45
|
+
For one shared immutable decision log, derive the writer set from actual task
|
|
46
|
+
text. A `merge_order` entry must match an actual edge. An `integration_owner`
|
|
47
|
+
entry is valid only when exactly one story declares the final shared-file write
|
|
48
|
+
and the other supplies distinct integration inputs. Preserve landed entries
|
|
49
|
+
byte-for-byte. A cross-spec `concurrent` entry is advisory only; the final
|
|
50
|
+
release DAG resolves it.
|