Browse Source

G-047 refined: per-developer commit-target override + fossil machinery carve-out

Rework the proposed G-047 for mixed git/fossil-preferring teams: committed
[workflow] vcs in punkproject.toml declares the team primary (authoritative
interchange); the same key in an uncommitted punkproject.local.toml redirects
an individual developer's unqualified commit instructions. Resolution order:
local override > project field > filesystem detection. Drops the
one-directional batched-checkin claim (developer committing granularly to the
secondary owns batching up to the primary) and records that punk internal
machinery (punkcheck related-project tracking, G-027 pull, G-016 discovery)
stays standardized on fossil regardless of the declared field. New detail
file records rejected alternatives and rationale.

Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
Julian Noble 6 days ago
parent
commit
a012142512
  1. 9
      GOALS.md
  2. 37
      goals/G-047-declared-primary-vcs.md

9
GOALS.md

@ -327,7 +327,8 @@ Detail: goals/G-046-punkargs-deferred-help-and-fixes.md
Goal: argument resolution no longer processes -help and other display-only fields - their tstr expansion is deferred to display time (separately cached, per the existing in-source review notes) - so first parse of heavily documented commands gets measurably faster and definitions whose -help calls punk::args-parsing commands (the punk::ansi::mark_columns class) neither loop nor stall; alongside, the mechanical defects pinned by the characterization suites are fixed: @dynamic double-substituted multiline values align at their insertion column, prefix-normalized choice values keep the same shape as exact input, the -return string renderer aligns cmd-help continuations under the first line, and the misleading goodargs parse-error prefix in 'i <cmd> <args>' output is fixed.
Acceptance: parsing/argument resolution provably skips -help expansion (a definition whose -help contains a ${[...]} that would error or record its invocation shows the substitution did NOT run during a parse-only path, only for help display); first parse of punk::ansi::mark_columns drops from ~4s to well under a second with 'i punk::ansi::mark_columns' still rendering the embedded example, and a -help that parses its OWN definition id resolves or errors cleanly rather than looping; first-parse timing improves for at least one other heavily documented command (recorded in the detail file); rendering_atdynamic_multiline_help_insertion_GAP flips to all-aligned; choicegroups_imap_prefix_listwrap_GAP flips to shape-identical (prefix input yields the same plain string as exact input); the -return string renderer's cmd-help continuations align under the first line with relative indents preserved (rendering_string_renderer_characterization updated); the 'Bad number of leading values...' prefix shown by goodargs parsing in 'i string is'-style output is reworded or suppressed for the usage-display path; full punk::args and punk::ns suites pass with no non-GAP expectations weakened.
### G-047 [proposed] Declared primary VCS field in punkproject.toml
Scope: punkproject.toml (schema), root AGENTS.md (Commit Conventions (any VCS) section), src/project_layouts/ (layout template payload - default values only; project.new validation is follow-on work)
Goal: a `[workflow] vcs = "<system>"` field in punkproject.toml declares the team's primary upstream VCS - the default target for unqualified "commit"/"checkin" requests and the system new commits land in first, with the secondary (when present) caught up via batched checkins - so agents and tooling read the declared field rather than guessing from filesystem presence or hardcoded defaults; punkshell itself carries `[workflow] vcs = "git"` and derived-project layout templates carry their own default (fossil).
Acceptance: punkshell's punkproject.toml contains `[workflow] vcs = "git"` and root AGENTS.md "Commit Conventions (any VCS)" names the field as the preferred source with the existing prose as fallback for projects without the field; a reader (agent or tool) resolving the primary VCS for a project root (anchored via the punk::repo::is_project_root marker, not a naive walk-up) trusts the field when present and falls back to filesystem detection when absent; a subproject's own punkproject.toml under the root tree is not confused for the root project's declaration (proven by a root-anchored reader ignoring a nested punkproject.toml's `[workflow] vcs`); the field is documented as advisory to G-016's projects.work discovery (detection remains the fallback); punkproject.toml version is patch-bumped with a CHANGELOG entry for the schema addition; make.tcl/project.new validation of the field against detected VCS systems is explicitly out of scope here (follow-on work).
### G-047 [proposed] Declared primary VCS in punkproject.toml with per-developer commit-target override
Scope: punkproject.toml (schema), punkproject.local.toml (new, uncommitted per-checkout override), root AGENTS.md (Commit Conventions (any VCS) section), .gitignore + .fossil-settings/ignore-glob (ignore rules for the local file, per the coexistence contract), src/project_layouts/ (layout template payload - default values and ignore seeding only; project.new validation is follow-on work)
Detail: goals/G-047-declared-primary-vcs.md
Goal: a `[workflow] vcs = "<system>"` field in punkproject.toml declares the team's primary upstream VCS - the authoritative interchange history and the default target for unqualified "commit"/"checkin" requests - while the same field in an uncommitted per-checkout punkproject.local.toml lets an individual developer redirect their own unqualified commit instructions to their preferred system (mixed git/fossil-preferring teams), resolution order local override > project field > filesystem detection; the declaration governs developer commit workflow only - punk internal machinery (punkcheck tracking of related projects, upstream infrastructure pull per G-027, central project discovery per G-016) remains standardized on fossil regardless of the declared field; punkshell itself carries `[workflow] vcs = "git"` and derived-project layout templates default to fossil.
Acceptance: punkshell's punkproject.toml contains `[workflow] vcs = "git"`, and root AGENTS.md "Commit Conventions (any VCS)" documents the resolution order (punkproject.local.toml field, then punkproject.toml field, then filesystem detection, with the existing prose as final fallback) as the source agents consult for unqualified commit/checkin requests; punkproject.local.toml is ignored by both VCS per the .fossil-settings coexistence contract (git check-ignore matches it, ignore-glob covers it, the contract's verification comparisons stay clean); a reader resolving the primary VCS anchors at the project root via the punk::repo::is_project_root marker and ignores any nested punkproject.toml/punkproject.local.toml `[workflow] vcs`; the fossil-machinery carve-out is recorded in root AGENTS.md alongside the field documentation (a git-primary ecosystem project still maintains its fossil repo for punkcheck/pull/discovery machinery), and the field stays advisory to G-016 discovery with detection as fallback; the mixed-team sync semantics are documented (team primary = authoritative interchange; a developer committing granularly to the secondary owns batching their work up to the primary); project version patch-bumped with a CHANGELOG entry for the schema addition; make.tcl/project.new validation of the field against detected VCS systems stays out of scope (follow-on work).

37
goals/G-047-declared-primary-vcs.md

@ -0,0 +1,37 @@
# G-047 Declared primary VCS in punkproject.toml with per-developer commit-target override
Status: proposed
Scope: punkproject.toml (schema), punkproject.local.toml (new, uncommitted per-checkout override), root AGENTS.md (Commit Conventions (any VCS) section), .gitignore + .fossil-settings/ignore-glob (ignore rules for the local file, per the coexistence contract), src/project_layouts/ (layout template payload - default values and ignore seeding only; project.new validation is follow-on work)
Acceptance: punkshell's punkproject.toml contains `[workflow] vcs = "git"`, and root AGENTS.md "Commit Conventions (any VCS)" documents the resolution order (punkproject.local.toml field, then punkproject.toml field, then filesystem detection, with the existing prose as final fallback) as the source agents consult for unqualified commit/checkin requests; punkproject.local.toml is ignored by both VCS per the .fossil-settings coexistence contract (git check-ignore matches it, ignore-glob covers it, the contract's verification comparisons stay clean); a reader resolving the primary VCS anchors at the project root via the punk::repo::is_project_root marker and ignores any nested punkproject.toml/punkproject.local.toml `[workflow] vcs`; the fossil-machinery carve-out is recorded in root AGENTS.md alongside the field documentation (a git-primary ecosystem project still maintains its fossil repo for punkcheck/pull/discovery machinery), and the field stays advisory to G-016 discovery with detection as fallback; the mixed-team sync semantics are documented (team primary = authoritative interchange; a developer committing granularly to the secondary owns batching their work up to the primary); project version patch-bumped with a CHANGELOG entry for the schema addition; make.tcl/project.new validation of the field against detected VCS systems stays out of scope (follow-on work).
## Context
Agents and tooling currently guess a project's commit target from filesystem presence (`.git`, `.fslckout`) or hardcoded convention. Punkshell itself is dual-VCS (git-primary for developer history, fossil maintained in parallel), and projects generated from punkshell layouts start fossil-only but may adopt git. An unqualified "commit this" instruction therefore has no declared, machine-readable answer.
The original G-047 draft (2026-07-08) declared a single team-wide primary with the secondary "caught up via batched checkins" - a one-directional model. Refined 2026-07-09 for small mixed teams where one developer prefers git for granular checkins and another prefers fossil:
1. A committed field cannot express individual preference - it is shared state. A second, uncommitted per-checkout file carries the personal override.
2. With mixed preferences both systems receive granular commits, so "secondary caught up via batching" is no longer a single-owner, single-direction activity. The declared team field marks the authoritative interchange; each developer whose granular checkins land in the secondary owns batching their own work up to the primary. This is a documented workflow convention, not tooling - bidirectional git<->fossil auto-sync is explicitly not what the field promises.
3. The field needs an explicit carve-out so `vcs = "git"` is never read as license to drop fossil: punk internal machinery - punkcheck tracking of related projects, upstream infrastructure pull (G-027), central project discovery via the fossil config db (G-016) - remains standardized on fossil. A git-primary ecosystem project still maintains its fossil repo for the machinery, exactly punkshell's own arrangement.
## Approach
- `[workflow] vcs = "<system>"` in punkproject.toml: team primary - authoritative interchange history and default commit target.
- Same key in punkproject.local.toml (project root, never committed, ignored by both VCS): per-developer/per-checkout override for unqualified commit instructions.
- Resolution order: local override > project field > filesystem detection > existing AGENTS.md prose.
- Same key in both files keeps the resolver trivial; the file's committed/uncommitted status carries the team-vs-personal semantics (a distinct key like `commit_vcs` would let one file express both but splits the concept for little gain).
- Readers anchor at the project root via the punk::repo::is_project_root marker so a nested subproject's declaration is never mistaken for the root's.
- The local file's ignore rules follow the .fossil-settings/ coexistence contract: `.gitignore` is canonical, `ignore-glob` hand-derived (no negation in fossil globs; the file is a simple positive pattern in both).
## Alternatives considered
- **Committed per-developer map** (e.g. `[workflow.developers]` in punkproject.toml keyed by identity) - rejected: publishes personal preferences into shared history, requires identity resolution (git user.name/email vs fossil login vs harness user), and churns a shared file on preference changes.
- **User-level punk config (XDG, G-014)** - rejected for now: global across projects rather than per-project/per-checkout, and not agent-readable until G-014 lands. Could later feed a default into the same resolution chain below the local file; out of scope here.
- **Environment variable** - rejected: invisible to inspection, not durable across sessions, and per-process rather than per-checkout.
- **Extending G-027 with the fossil-standardization statement** - not done: G-027's provenance basis is .punkcheck records (VCS-neutral) and its VCS-state checks already cover both systems via G-026. The carve-out lives in this goal's contract to avoid a second place to keep in sync.
## Notes
- G-016 (projects.work git discovery) is unchanged: fossil discovery stays central-config-db based and this field is advisory to it, detection remaining the fallback.
- Layout templates seed `vcs = "fossil"` as the generated-project default plus the punkproject.local.toml ignore rules in both ignore systems.
- Validation of the declared field against the VCS systems actually present (make.tcl / project.new) is follow-on work, deliberately out of scope.
Loading…
Cancel
Save