Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Governed architecture roadmap

- [ ] Deliver [ticket-059](project/ticket-059/README.md): align the default
Python strategy and pip/pipenv descriptors with ticket-058's retry-safe
Twine contract. State: `IN_PROGRESS / PUBLICATION`; 618 tests (2 skips),
scoped Ruff and governance pass; classification:
`BUG / P1 / regression`; depends on ticket-058.

- [x] Deliver [ticket-058](project/ticket-058/README.md): make configured Twine
publication retries idempotent at runtime and migrate legacy commands
through doctor PY013. State: `DONE / DONE`; configuration producers and
Expand Down
4 changes: 2 additions & 2 deletions goal/config/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@
"python": {
"test": "pytest tests/ -v",
"build": "python -m build",
"publish": "twine upload dist/{project_name}-{version}*", # placeholder, replaced on init
"publish": "twine upload --skip-existing dist/{project_name}-{version}*", # placeholder, replaced on init
"publish_enabled": True,
"dependencies": {
"file": "requirements.txt",
Expand Down Expand Up @@ -477,7 +477,7 @@
},
}

from goal.validators.tokens import get_default_token_patterns
from goal.validators.tokens import get_default_token_patterns # noqa: E402

DEFAULT_CONFIG["advanced"]["file_validation"]["token_patterns"] = (
get_default_token_patterns()
Expand Down
4 changes: 2 additions & 2 deletions goal/package_managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def __post_init__(self):
update_cmd="pip install --upgrade {package}",
test_cmd="pytest",
build_cmd="python -m build",
publish_cmd="python -m twine upload dist/*",
publish_cmd="python -m twine upload --skip-existing dist/*",
run_cmd="python {command}",
version_cmd="python setup.py --version",
priority=1,
Expand Down Expand Up @@ -116,7 +116,7 @@ def __post_init__(self):
update_cmd="pipenv update",
test_cmd="pipenv run pytest",
build_cmd="pipenv run python -m build",
publish_cmd="pipenv run python -m twine upload dist/*",
publish_cmd="pipenv run python -m twine upload --skip-existing dist/*",
run_cmd="pipenv run {command}",
version_cmd="pipenv --version",
priority=6,
Expand Down
1 change: 1 addition & 0 deletions project/TICKETS.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,5 @@ This file indexes governance tickets without taking ownership of
| **ticket-056** | [`README.md`](./ticket-056/README.md) | [`preprompt.md`](./ticket-056/preprompt.md) | - | [`ai-codex.md`](./ticket-056/ai-codex.md) | [`ai-codex-logs.txt`](./ticket-056/ai-codex-logs.txt) | [`changelog.md`](./ticket-056/changelog.md) |
| **ticket-057** | [`README.md`](./ticket-057/README.md) | [`preprompt.md`](./ticket-057/preprompt.md) | - | [`ai-codex.md`](./ticket-057/ai-codex.md) | [`ai-codex-logs.txt`](./ticket-057/ai-codex-logs.txt) | [`changelog.md`](./ticket-057/changelog.md) |
| **ticket-058** | [`README.md`](./ticket-058/README.md) | [`preprompt.md`](./ticket-058/preprompt.md) | - | [`ai-codex.md`](./ticket-058/ai-codex.md) | [`ai-codex-logs.txt`](./ticket-058/ai-codex-logs.txt) | [`changelog.md`](./ticket-058/changelog.md) |
| **ticket-059** | [`README.md`](./ticket-059/README.md) | [`preprompt.md`](./ticket-059/preprompt.md) | - | [`ai-codex.md`](./ticket-059/ai-codex.md) | [`ai-codex-logs.txt`](./ticket-059/ai-codex-logs.txt) | [`changelog.md`](./ticket-059/changelog.md) |
<!-- AUTO:TICKET_INDEX:END -->
46 changes: 46 additions & 0 deletions project/ticket-059/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Ticket 059: Align built-in Python publish commands

- **ID**: ticket-059
- **Owner**: unresolved:human
- **Status**: IN_PROGRESS
- **Workflow state**: PUBLICATION
- **Created**: 2026-08-12

## Goal and scope

Align every built-in Goal configuration producer with the retry-safe Twine
contract delivered by ticket-058. Fresh default configurations and the legacy
`pip` / `pipenv` package-manager descriptors must include exactly one
`--skip-existing`, so newly generated projects are safe before doctor or the
runtime boundary needs to repair them.

## Acceptance criteria

- [x] AC-01: The user's instruction to repair and continue records
`SESSION_EXECUTION_AUTHORIZATION` for this bounded regression fix.
- [x] AC-02: The default Python strategy emits the canonical retry-safe Twine
command.
- [x] AC-03: The `pip` and `pipenv` package-manager descriptors emit
retry-safe Twine commands without changing non-Twine managers.
- [x] AC-04: Focused/full tests, Ruff and governance pass before protected
exact-head delivery.

## Non-goals

- Do not change runtime normalization or doctor migration from ticket-058.
- Do not edit governance-owned `goal.yaml`; that is a dependent ticket.
- Do not change versions, dependencies or public interfaces.

## Participants

- Human participant: unresolved; no user-* file was created by this script.
- Agent participant: [ai-codex.md](ai-codex.md)

## Validation evidence

- Three focused regressions prove the default, `pip` and `pipenv` commands
contain the canonical flag exactly where expected.
- The full suite passes 618 tests with 2 existing skips; scoped Ruff,
governance (0 errors/0 warnings) and whitespace checks pass.
- The touched constants module's existing late import is now explicitly marked
`noqa: E402`; import order and runtime behavior are unchanged.
5 changes: 5 additions & 0 deletions project/ticket-059/ai-codex-logs.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
2026-08-12T18:08:51Z ticket-059 allocated on clean accepted base d26817b4132d5a110ec0c4c9e3dc3672f94e2508 after ticket-058 closure and workspace cleanup.
2026-08-12T18:08:51Z SESSION_EXECUTION_AUTHORIZATION recorded from the user's repeated instruction to repair and continue.
2026-08-12T18:08:51Z scope: one built-in publish-configuration component containing the default Python strategy, pip/pipenv descriptors and one focused test module; governance-owned goal.yaml deferred to a dependent ticket.
2026-08-12T18:11:08Z implementation: DEFAULT_CONFIG, pip and pipenv now emit exactly one --skip-existing in their Twine upload command; non-Twine descriptors are byte-unchanged. Added three exact regression cases.
2026-08-12T18:11:08Z validation: 3 focused PASS; 618 full PASS/2 SKIP; scoped Ruff PASS; governance GOV-PASS 0 errors/0 warnings; git diff --check PASS. Existing late constants import received an explicit E402 exemption with no runtime change.
41 changes: 41 additions & 0 deletions project/ticket-059/ai-codex.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
participant-id: agent:codex
participant: codex
role: agent
ticket: ticket-059
---
# Participant: codex (AI agent)

## Understanding

Ticket-058 guarantees safety at execution and repairs legacy repositories, but
fresh configurations still start stale because three built-in producers omit
`--skip-existing`. This ticket removes that internal inconsistency without
crossing into governance-owned `goal.yaml`.

## Execution plan

1. Bind the change to one producer component and three implementation files
allowed by the delivery budget.
2. Add regression assertions for the default strategy and package-manager
descriptors.
3. Run focused/full validation and deliver the exact candidate through
protected CI and Validator Agent review.

## Actual changes

- Initialized the bounded ticket and recorded SESSION_EXECUTION_AUTHORIZATION
from the request to execute this work.
- Kept `goal.yaml` in a separate dependent governance ticket so ownership and
implementation budgets remain enforceable.
- Updated the default Python strategy and both Twine package-manager
descriptors, with exact regressions for every producer.
- Passed 3 focused and 618 full tests (2 existing skips), scoped Ruff,
governance and whitespace validation; moved to PUBLICATION for protected
exact-head review.

## Blockers

- None inside the recorded intent; proceed without a second confirmation.
- New authority remains required for destructive action, secret access, new
external coordination, material objective expansion and trusted merge.
10 changes: 10 additions & 0 deletions project/ticket-059/changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Ticket Changelog (ticket-059)

## [0.1.0] - 2026-08-12

- Initial governance scaffold created.
- No human participant identity or content was generated.
- Bounded the retry-safe producer alignment to default configuration and the
package-manager registry; retained `goal.yaml` as separate governance work.
- Added explicit retry safety to all three built-in Twine command producers and
exact regressions; full tests, Ruff and governance pass.
87 changes: 87 additions & 0 deletions project/ticket-059/intent.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
"schema": "new-project.intent/v3",
"ticket": "ticket-059",
"summary": "Align built-in Python publish commands",
"workstream": "application",
"classification": {
"kind": "BUG",
"priority": "P1",
"origin": "regression"
},
"allowedPaths": [
"goal/config/constants.py",
"goal/package_managers.py",
"tests/test_package_managers.py",
"project/ticket-059/**",
"TODO.md",
"project/TICKETS.md"
],
"forbiddenPaths": [
"project/ticket-*/user-*.md",
"goal.yaml",
"VERSION",
"pyproject.toml",
"uv.lock",
"goal/__init__.py",
".github/**"
],
"stacks": ["python"],
"dependsOn": ["ticket-058"],
"conflictsWith": [],
"integrationTicket": null,
"delivery": {
"acceptedBaseSha": "d26817b4132d5a110ec0c4c9e3dc3672f94e2508",
"targetBranch": "main",
"outcome": "Every built-in Goal producer emits retry-safe Twine upload commands",
"nonGoals": [
"Do not change runtime or doctor behavior",
"Do not edit governance-owned Goal configuration",
"Do not change package versions or dependencies"
],
"complexity": "S",
"estimatedMinutes": 20,
"budgets": {
"maxImplementationFiles": 3,
"maxAffectedComponents": 2,
"maxPublicInterfaceChanges": 0,
"maxRuntimeDependencies": 0
},
"architecture": {
"status": "accepted",
"decision": "Make retry safety explicit at each built-in configuration source while retaining ticket-058 as the final runtime defense",
"components": [
{
"name": "built-in-publish-configuration",
"paths": [
"goal/config/constants.py",
"goal/package_managers.py",
"tests/test_package_managers.py"
]
}
],
"responsibilityChanges": false,
"interfaceChanges": [],
"dataChanges": [],
"ui": {"impact": "none", "states": [], "evidence": []},
"rollback": "Revert the bounded implementation PR; ticket-058 runtime normalization still protects execution"
},
"runtimeDependencies": [],
"validation": [
{
"criterion": "AC-02",
"commands": ["pytest -q tests/test_package_managers.py"],
"evidence": "project/ticket-059/ai-codex-logs.txt"
},
{
"criterion": "AC-03",
"commands": ["pytest -q tests/test_package_managers.py"],
"evidence": "project/ticket-059/ai-codex-logs.txt"
},
{
"criterion": "AC-04",
"commands": ["pytest -q", "ruff check scoped paths", "./project/governance-check.sh"],
"evidence": "project/ticket-059/ai-codex-logs.txt"
}
]
}
}
12 changes: 12 additions & 0 deletions project/ticket-059/preprompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Ticket preprompt

- **Task ID**: ticket-059
- **Task title**: Align built-in Python publish commands
- **Created**: 2026-08-12T18:08:39Z

Keep executable implementation outside this governance/evidence directory.
Read a human-owned user-*.md file only when one exists.
The request to execute this work creates SESSION_EXECUTION_AUTHORIZATION;
proceed within the recorded intent without a redundant confirmation prompt.
Require new authority for destructive action, secrets, external coordination,
material objective expansion and trusted merge approval.
26 changes: 26 additions & 0 deletions tests/test_package_managers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""Regression tests for built-in package publication commands."""

import pytest

from goal.config.constants import DEFAULT_CONFIG
from goal.package_managers import PACKAGE_MANAGERS


def test_default_python_publish_command_is_retry_safe():
assert DEFAULT_CONFIG["strategies"]["python"]["publish"] == (
"twine upload --skip-existing dist/{project_name}-{version}*"
)


@pytest.mark.parametrize(
("manager", "expected"),
[
("pip", "python -m twine upload --skip-existing dist/*"),
(
"pipenv",
"pipenv run python -m twine upload --skip-existing dist/*",
),
],
)
def test_twine_package_manager_publish_commands_are_retry_safe(manager, expected):
assert PACKAGE_MANAGERS[manager].publish_cmd == expected