From 99af43c8be221f42e7c12f4ed16173741a2127da Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Sun, 12 Jul 2026 00:18:33 +1000 Subject: [PATCH] goals: G-062 achieved archival + archive-loss prevention (sweep rules, backlink markers, goals_lint) Finalises the G-062 achieved flip staged by the prior session (punkshell 0.12.1): LICENSE.txt (BSD-2-Clause, Julian Marcel Noble 2023-2026) at the repo root, README/punkproject.toml/AGENTS.md license declarations, index record to GOALS-archive.md and detail file to goals/archive/. Archive-loss prevention, from the G-015 incident (its achieved-status verification parenthetical was silently dropped by the 2026-07-11 two-tier restructure's Status-line normalisation; the text is restored to the G-015 archive file's Notes with provenance): - root AGENTS.md 'Doc Restructures': deleted-line conservation check before committing bulk doc migrations, structured-field-normalisation hazard (relocate prose to body sections first), moves separated from edits - goals/AGENTS.md: lintable header field grammar (one line per field, bare Status values), flip-time verification evidence recorded in the body, the archive move content-identical, and a new archive-time reference sweep: pending-tense mentions of the archived goal updated in the live tier, and actionable archived notes pointed to from the affected live goal's Notes - GOALS.md maintenance rules: achieved-flip clause extended to require the evidence write-up and the reference sweep Retroactive reference sweep over all 12 archived goals (25 live detail files): pending-tense fixes (G-002 G-008 G-013 G-016 G-017 G-021 G-022 G-031 G-042 G-044 G-050 - G-017's Goal/Acceptance annotated as gate-satisfied, contract meaning unchanged), forward pointers pushed from archived notes (G-062 license-seeding follow-on -> G-012/G-027, G-037 vendorlib/vfs drift semantics -> G-024, G-058 static-baseline mechanism -> G-005), and one 'Archived-goal references' Notes bullet per remaining referencing file so every live mention of an archived goal is resolvable without consulting the archive index. scriptlib/developer/goals_lint.tcl (new, plain tclsh): validates detail-file header grammar, strict status values in both tiers, orphan rules in both directions, Status/Scope mirror consistency, plus an informational (never fatal) warning for live files referencing an archived goal with no achieved/archive marker - baseline now zero warnings. Root AGENTS.md scriptlib/developer ownership note widened to cover developer utilities. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com --- AGENTS.md | 12 +- CHANGELOG.md | 4 + GOALS-archive.md | 4 + GOALS.md | 6 +- LICENSE.txt | 24 ++ README.md | 2 +- goals/AGENTS.md | 7 +- goals/G-002-non-nested-subshell.md | 2 +- goals/G-005-zig-build-infrastructure.md | 5 + goals/G-008-scoped-console-state.md | 2 +- goals/G-010-subshell-tree-navigation.md | 1 + goals/G-011-console-stderr-semantics.md | 1 + goals/G-012-template-payload-safety.md | 3 + goals/G-013-raw-mode-default.md | 4 +- goals/G-014-punk-config-toml.md | 4 + goals/G-016-projects-work-git-discovery.md | 3 +- goals/G-017-agent-project-discovery.md | 4 +- goals/G-020-screencap-input-module.md | 1 + goals/G-021-agent-visual-verification.md | 2 +- goals/G-022-fossil-rename-punkshell.md | 5 +- goals/G-024-mapvfs-toml.md | 5 + goals/G-025-exe-selfreport.md | 1 + goals/G-027-derived-project-pull-updates.md | 3 + goals/G-030-maketcl-punkargs.md | 1 + goals/G-031-componentized-kit-boot.md | 9 +- goals/G-032-launcher-punkargs.md | 1 + goals/G-033-proj-mode-cwd-project.md | 1 + goals/G-038-piped-session-continuity.md | 1 + goals/G-039-orphan-console-spin.md | 1 + goals/G-041-punkargs-form-matching.md | 1 + goals/G-042-subshell-help-topics.md | 5 +- goals/G-044-repl-command-completion.md | 3 +- goals/G-045-punkargs-authoring-ergonomics.md | 1 + goals/G-050-synopsis-validity-marking.md | 2 +- goals/G-052-oo-method-autodef.md | 1 + goals/G-053-punkargs-multiple-ranges.md | 1 + goals/G-055-tclcore-regen-workflow.md | 1 + goals/G-056-punkargs-word-wrapping.md | 1 + goals/G-060-qemu-test-matrix.md | 1 + goals/G-061-pseudoconsole-expect.md | 1 + goals/G-063-package-license-tracking.md | 1 + .../G-015-script-subcommand-piped-stdin.md | 11 + .../G-062-project-license-file.md | 19 +- punkproject.toml | 3 +- scriptlib/developer/goals_lint.tcl | 218 ++++++++++++++++++ 45 files changed, 357 insertions(+), 32 deletions(-) create mode 100644 LICENSE.txt rename goals/{ => archive}/G-062-project-license-file.md (54%) create mode 100644 scriptlib/developer/goals_lint.tcl diff --git a/AGENTS.md b/AGENTS.md index 849ac278..8d607e16 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -38,6 +38,14 @@ Update the closest owning AGENTS.md when a change affects: Update parent docs when parent-level structure, ownership, workflow, or child index changes. Update child docs when parent changes alter local rules. Remove stale or contradictory text immediately. Small edits that do not change behavior or contracts may leave docs unchanged, but the DOX pass still must happen. +## Doc Restructures + +Rules for any bulk restructure, normalisation, or migration of documentation (index reshapes, field-format normalisation, file moves/renames across many docs): + +- Conservation check before committing: extract the deleted lines from the diff and account for every non-blank one - it must be relocated verbatim somewhere in the new tree, be pure boilerplate/stub text (e.g. "see index (canonical)" placeholders), or be a deliberate drop named explicitly in the commit message. A preservation claim in a commit message ("bodies preserved untouched") must be backed by this check, not intent. Mechanics: `git diff | grep '^-[^-]'` (or the VCS equivalent), then `grep -F` each deleted line against the restructured files. +- Structured-field normalisation is the highest-risk step: prose riding a structured line (a status field, a header mirror) is invisible to a "preserve bodies" intent and is exactly what normalisation deletes. Relocate such prose to a body section first, then normalise. +- Separate moves from edits: a file move/rename commit is content-identical; any reconciliation edits land in an adjacent commit. Combined move+edit diffs are where losses hide. + ## Hierarchy - Root AGENTS.md is the DOX rail: project-wide instructions, global preferences, durable workflow rules, and the top-level Child DOX Index @@ -185,7 +193,7 @@ The project version is fully independent of module versions. A module bump (even - `goals/archive/` — Detail files for achieved/archived goals - Directories agents should not directly modify (no child DOX needed): - `callbacks/` — Experimental shellspy features, user-only - - `scriptlib/` — Shared utilities + manual tests, user-only. EXCEPTIONS: `scriptlib/_punktest/` is test-owned (fixtures for `src/tests/shell/testsuites/punkexe/scriptexec.test`, resolved via `lib:_punktest/`); agents may manage that subfolder as part of test work. `scriptlib/developer/` holds agent-authored developer showcase/demo apps (created at user request 2026-07-11, e.g `tkconsole_demo.tcl` for the G-001 tk console backend); agents may add or update demos there when the user asks for one. The rest of `scriptlib/` stays user-only. + - `scriptlib/` — Shared utilities + manual tests, user-only. EXCEPTIONS: `scriptlib/_punktest/` is test-owned (fixtures for `src/tests/shell/testsuites/punkexe/scriptexec.test`, resolved via `lib:_punktest/`); agents may manage that subfolder as part of test work. `scriptlib/developer/` holds agent-authored developer showcase/demo apps and developer utility scripts (created at user request 2026-07-11, e.g `tkconsole_demo.tcl` for the G-001 tk console backend, `goals_lint.tcl` for the goals doc contracts per goals/AGENTS.md Verification); agents may add or update entries there when the user asks for one. The rest of `scriptlib/` stays user-only. - `bin/` — Built binaries and helpers, build output target. This includes the polyglot `.cmd` launcher/utility scripts (e.g `bin/runtime.cmd`): they are GENERATED by the punk::mix scriptwrap machinery from sources under `src/scriptapps/` — a request to "fix bin/.cmd" means editing `src/scriptapps/.*` + `_wrap.toml` and re-wrapping (see bin/AGENTS.md), never editing the output - `modules/` (root) — Build output target for `tclsh src/make.tcl modules` - `lib/` (root) — Build output target for `tclsh src/make.tcl libs` @@ -195,7 +203,7 @@ The project version is fully independent of module versions. A module bump (even ## Repo-wide Notes -- Punkshell (a.k.a. Punk Shell) is an experimental, alpha-level alternative Tcl shell under the BSD license; its primary language is Tcl. Note: "shellspy" (lowercase) refers only to the experimental `shellspy` subcommand available at launch — it is not the project name. +- Punkshell (a.k.a. Punk Shell) is an experimental, alpha-level alternative Tcl shell licensed under BSD-2-Clause (see `LICENSE.txt` at the repo root); its primary language is Tcl. Note: "shellspy" (lowercase) refers only to the experimental `shellspy` subcommand available at launch — it is not the project name. - The project extends Tcl with ANSI terminal capabilities, functional and pattern-matching language features, and a comprehensive module ecosystem. - This root file is intentionally limited to DOX governance, global ownership boundaries, and the top-level Child DOX Index. - Source-tree build, testing, linting, and file-resolution workflow lives in `src/AGENTS.md`. diff --git a/CHANGELOG.md b/CHANGELOG.md index cabdf18d..1ce03af6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ The latest `## [X.Y.Z]` header must match the `version` field in `punkproject.to Entries are newest-first; one bullet per notable change. See the root `AGENTS.md` "Project Versioning" section for the bump policy. +## [0.12.1] - 2026-07-11 + +- G-062 achieved: canonical project license declared as BSD-2-Clause. `LICENSE.txt` added at the repo root with the standard BSD-2-Clause text (copyright Julian Marcel Noble, 2023-2026); `README.md` names BSD-2-Clause and points at `LICENSE.txt`; root `AGENTS.md` Repo-wide Notes names the license precisely; `punkproject.toml` `[project]` carries `license = "BSD-2-Clause"`. Repo-sweep found no top-level license claims contradicting it (vendored library licenses and module-level generated docs are not project-level claims). + ## [0.12.0] - 2026-07-11 - punk::args 0.6.0: command synopses (`s `, `i `, usage headers) now display small restricted choice sets as literal alternates — an argument whose choice pool (`-choices` plus `-choicegroups` members) has 1–3 members and `-choicerestricted` true renders those words unitalicised joined by `|` (e.g. `after cancel` shows literal `cancel`; a 3-choice option shows `(left|centre|right)`), matching the existing display style of `literal()`/`literalprefix()` type-alternates. Larger or unrestricted choice sets keep the italicised argname/type display and an explicit `-typesynopsis` always wins, so e.g. `textblock::frame -type (choice|)` is unchanged. Synopsis rendering of type-alternates, `-typesynopsis` passthrough (including documenter ANSI styling), and multi-element clause display gained characterization test coverage (`synopsis.test`). diff --git a/GOALS-archive.md b/GOALS-archive.md index 215faa66..1b76124a 100644 --- a/GOALS-archive.md +++ b/GOALS-archive.md @@ -61,3 +61,7 @@ Acceptance: a punk91-style kit (tclsfe-x64 + punk9win.vfs, no thread dll in the ### G-059 [achieved 2026-07-11] WSL detection and suitability probing for driving unix-side tests from Windows → detail: goals/archive/G-059-wsl-test-driving.md Scope: src/tests/ (capability probe helpers + constraint-gated cases in existing suites, e.g the unix sh-payload execution test in modules/punk/mix/testsuites/scriptwrap/multishell.test and a runtime.bash behaviour test), src/tests/AGENTS.md (enablement notes) Acceptance: a documented probe helper yields a wsl_linux_available constraint whose checks are capability-based (distro launches and answers uname/tool probes; staging into a native tempdir works) and which cannot misfire on wsl.exe-present-but-unusable installs (no distro, WSL1 limitations, broken interop); the currently unix-gated multishell sh-payload execution test runs green via WSL on a suitable machine and still skips cleanly elsewhere; at least one runtime.bash behaviour test (active/use/run resolution against a fixture runtime folder) runs inside WSL - all such tests executing from a native-filesystem staging dir with the shared path used only for one-way copy-in/out; the Windows checkout's git and fossil state is untouched by a WSL-gated run (verifiable: git status/fossil changes identical before and after); suite results on a WSL-less machine are unchanged (skips, not failures); enablement/limitations and the staging pattern recorded in src/tests/AGENTS.md. + +### G-062 [achieved 2026-07-11] Canonical project license: BSD-2-Clause LICENSE file with SPDX-identified references → detail: goals/archive/G-062-project-license-file.md +Scope: LICENSE.txt (new, repo root), README.md, punkproject.toml ([project] license field), AGENTS.md (Repo-wide Notes license mention) +Acceptance: LICENSE.txt exists at the repo root containing the standard BSD-2-Clause text with a real copyright line; README.md names BSD-2-Clause and points at LICENSE.txt; root AGENTS.md Repo-wide Notes names the license precisely; punkproject.toml [project] carries license = "BSD-2-Clause"; a repo-sweep for top-level license claims finds none contradicting it (sweep result recorded here). diff --git a/GOALS.md b/GOALS.md index 4a3dc4ad..66632781 100644 --- a/GOALS.md +++ b/GOALS.md @@ -38,7 +38,7 @@ Every goal has a detail file; it holds the canonical Goal and Acceptance plus an - Suggesting is always allowed and encouraged when grounded in the work at hand: a discovered gap, a recurring manual step, a deferred design decision, or a natural follow-on that fits what is currently being worked on. Flag it as a candidate goal in conversation or the completion report, optionally with a drafted entry ready for approval. A suggestion is not an edit - nothing is written to this file or `goals/` until the user approves per the proposal-first rule. - The goal contract spans both tiers: the index entry (title, status tag, Scope) and the detail file's `Goal:` and `Acceptance:` lines. - Proposal-first: before writing a new goal or changing any contract element in either tier, show the user the proposed wording - the full entry plus detail-file header for a new goal, the changed clause(s) for an edit - and get explicit approval. If the user already supplied or approved the exact wording this session, apply it and report what was written. -- Exception (sanctioned autonomous edit): an agent whose work satisfies a goal's `Acceptance:` (judged against the detail file's criterion, never the index entry alone) must flip that goal to `achieved ` as part of its DOX closeout pass, archive it (entry to `GOALS-archive.md` per that file's format, detail file to `goals/archive/`), and report the flip in its completion summary. If the detail file carries a `## Progress` section, the flip additionally requires its remaining-work list to be resolved — empty, or each item verified satisfied; a partial increment never flips a goal. +- Exception (sanctioned autonomous edit): an agent whose work satisfies a goal's `Acceptance:` (judged against the detail file's criterion, never the index entry alone) must flip that goal to `achieved ` as part of its DOX closeout pass, archive it (entry to `GOALS-archive.md` per that file's format, detail file to `goals/archive/`), and report the flip in its completion summary. If the detail file carries a `## Progress` section, the flip additionally requires its remaining-work list to be resolved — empty, or each item verified satisfied; a partial increment never flips a goal. The flip records its verification evidence (what was verified, on which kits/runtimes, any remaining manual items) in the detail file's body — the `Status:` line stays bare `achieved `, per the header field grammar in `goals/AGENTS.md`. The flip also includes a reference sweep of the live tier (see `goals/AGENTS.md` Archive rules): pending-tense mentions of the archived goal updated to reflect achievement, and any of its notes actionable for a live goal pointed to from that goal's `## Notes`. - Agents must not flip `proposed` → `active`. They flag it in their completion report for the user to confirm. - Index entries carry no progress: the status tag is the only state the index records. Incremental progress on an `active` goal (what landed, what remains) is recorded in the detail file's `## Progress` section, never as annotations on the index entry. - Marking a goal `superseded by G-` or `abandoned` includes a test sweep: search the tree (at minimum `src/tests`) for `G-` references and for the tests named in the goal's detail-file Acceptance, and record each affected test's disposition in the superseding goal's detail file (or the abandoned goal's own): pinned expectations that transfer to the new goal, pins that stand down to plain behaviour characterization, and any that lapse. The sweep never deletes, skips, or weakens a test on its own — that still requires explicit user direction per `src/tests/AGENTS.md`. @@ -262,10 +262,6 @@ Detail: goals/G-060-qemu-test-matrix.md Scope: test-harness support (location TBD during the work: src/tests/testsupport/ and/or a small punk module), src/tests/shell/ (capability-gated interactive suites), goals/G-061-pseudoconsole-expect.md Detail: goals/G-061-pseudoconsole-expect.md -### G-062 [proposed] Canonical project license: BSD-2-Clause LICENSE file with SPDX-identified references -Scope: LICENSE.txt (new, repo root), README.md, punkproject.toml ([project] license field), AGENTS.md (Repo-wide Notes license mention) -Detail: goals/G-062-project-license-file.md - ### G-063 [proposed] Per-package license tracking: SPDX-normalized indications with copyleft audit Scope: src/modules (Meta license headers), src/vendormodules/ + src/vendorlib/ (vendored license recording), punk::mix module templates (%license% seeding), mapping module (new, name TBD), audit surface (src/make.tcl or dev commandset - TBD) Detail: goals/G-063-package-license-tracking.md diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..98ba1069 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,24 @@ +BSD 2-Clause License + +Copyright (c) 2023-2026 Julian Marcel Noble + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index 0cd5dfec..1d273a42 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## punkshell - an alternative Tcl Shell -BSD license +BSD-2-Clause license (see `LICENSE.txt`) Version 0.11.0 (2026-07) — this is **alpha** level software and still highly experimental. See `CHANGELOG.md` for recent changes. diff --git a/goals/AGENTS.md b/goals/AGENTS.md index 94bde3d0..a718e5eb 100644 --- a/goals/AGENTS.md +++ b/goals/AGENTS.md @@ -34,6 +34,8 @@ Goal: Acceptance: ``` +Header field grammar (lintable): each header field is one line carrying only its own content - never parenthetical narrative. `Status:` is exactly one of `proposed`, `active`, `abandoned`, `superseded`, or `achieved YYYY-MM-DD`. Verification evidence, design asides, and remaining manual items belong in body sections (`## Progress`, `## Notes`) - prose riding a header field is invisible to restructures that normalise those fields and gets silently dropped (root `AGENTS.md` "Doc Restructures"). + Optional sections after the header, only when they have real content: ``` @@ -61,6 +63,9 @@ When user-directed work on an `active` goal lands without satisfying its `Accept ### Archive - `goals/archive/` holds detail files for achieved goals. Archiving happens as part of the achieved flip (see the root `GOALS.md` maintenance rules): the detail file moves `goals/G--.md` → `goals/archive/G--.md` and the index entry moves to `GOALS-archive.md`. Do not rename the ID prefix. +- At the achieved flip, record the verification evidence in the detail file body (`## Progress` or `## Notes`): what was verified, on which kits/runtimes, design outcomes worth keeping, and any remaining manual items. The `Status:` line itself carries only `achieved YYYY-MM-DD` (header field grammar above). +- The archive move is content-identical: the file lands in `archive/` byte-for-byte as it left `goals/`, with the flip's content edits (Status line, evidence write-up) made before or after the move so the move diff is a pure rename (root `AGENTS.md` "Doc Restructures"). +- Reference sweep at archive time: grep the live tier (`goals/*.md`, `GOALS.md`) for the archived goal's ID. (a) Rewrite pending-tense phrasing ("once G-x lands", "after G-x is achieved") to reflect achievement, with the archive path - e.g. "(G-x, achieved - see goals/archive/G-x-.md)". (b) For each note in the archived detail file carrying actionable content for a live goal (a follow-on, dependency detail, or design decision that goal will need), add a one-line pointer to that live goal's `## Notes`: "G-x (archived) recorded - see goals/archive/G-x-.md". Mentions that are pure history need nothing. Rationale: an archived file is no longer edited, so its forward-pointing insights must be pushed to their targets when it leaves the active set. These are non-contract Notes updates - no pre-approval needed, report in the completion summary. - No orphan detail files: every file here (excluding `archive/` and this `AGENTS.md`) corresponds to a `proposed`, `active`, `abandoned` or `superseded` entry in root `GOALS.md`; every file under `archive/` corresponds to a record in `GOALS-archive.md`. ## Work Guidance @@ -69,7 +74,7 @@ LF line endings (per root AGENTS.md user preferences). ## Verification -None — this folder is documentation only. +`tclsh scriptlib/developer/goals_lint.tcl` — run after editing goal files or either index. Validates the detail-file header grammar (including the bare-`Status:` rule), index/detail orphan rules in both tiers, and the Status/Scope mirror consistency (plain tclsh, no dependencies; exit 0 clean, exit 1 with one line per finding). ## Child DOX Index diff --git a/goals/G-002-non-nested-subshell.md b/goals/G-002-non-nested-subshell.md index 35eefec7..d4ab537d 100644 --- a/goals/G-002-non-nested-subshell.md +++ b/goals/G-002-non-nested-subshell.md @@ -67,7 +67,7 @@ Split the subshell launch into layers. The canonical launch API (section 0) is a ## Notes -- Depends on G-001's launch-time console selection. Sequence G-001 before G-002. +- Depends on G-001's launch-time console selection - satisfied: G-001 achieved 2026-07-11 (see goals/archive/G-001-pluggable-console-backends.md), the prerequisite is in place. - The thread::send -async routing problem is the hardest open question in G-002. The standard Thread package targets the root interp of the receiving thread; the `code` sub-interp is where subshell code actually runs, so async messages miss it. `promise` (vendored at `src/vendormodules/promise-1.2.0.tm`) is the concrete canary — if `promise` works inside a subshell, the routing is correct. - The TODO at repl:3135-3139 frames the thread-extension investigation with a mainline-acceptance criterion. If that investigation concludes a fork is needed (customised Thread package and/or Tcl patch), create a follow-up goal for the fork's maintenance and upstreaming; do not let it grow inside G-002. The fork itself is out of scope for G-002's acceptance — G-002 is satisfied by whichever routing solution is found, not by the fork existing. - `tsv::` and `thread::cond` are already used in `codethread-999999.0a1.0.tm` (lines 203-218) for cross-thread result/status handoff. The inter-subshell comms layer should reuse the same primitives rather than introducing a new message bus. diff --git a/goals/G-005-zig-build-infrastructure.md b/goals/G-005-zig-build-infrastructure.md index 48a1c8e6..cd22a541 100644 --- a/goals/G-005-zig-build-infrastructure.md +++ b/goals/G-005-zig-build-infrastructure.md @@ -44,3 +44,8 @@ This goal is the primary mechanism for G-004's outcome. It is independent of and - The Tcl9-zig experiment is the seed; expect it to need expansion beyond Tcl9 to cover the full dependency set. Don't underestimate this — the experiment covers one component; the goal covers all committed binaries. - If the zig build for a particular dependency proves infeasible, G-006's download path is the fallback for that dependency, and the goal's acceptance is satisfied by the dependencies it does cover plus download for the rest. Document any such deferral. - No persisted prior chat on this topic was found in project sessions; the motivation is the user's stated intent and the existing Tcl9-zig experiment. +- G-058 (archived) shipped the static-baseline capture/seeding that zig-built static runtimes + will rely on (boot probe-loads empty-filename [info loaded] entries, seeds ifneeded mappings + into fabricated interps/threads); its detail file records the runtime-shape findings + (tclsfe stub replacement, composite-static exclusion) that a static-runtime build must + respect - see goals/archive/G-058-static-runtime-packages.md. diff --git a/goals/G-008-scoped-console-state.md b/goals/G-008-scoped-console-state.md index 70925a7b..7a8d635e 100644 --- a/goals/G-008-scoped-console-state.md +++ b/goals/G-008-scoped-console-state.md @@ -71,7 +71,7 @@ them through the owning context. ## Notes -- Sequence after G-007: the journal hooks belong at the same choke points the broker +- Sequence after G-007 (achieved 2026-07-05 - prerequisite in place): the journal hooks belong at the same choke points the broker instruments, and journaling must catch mutations originating in code interps - exactly what the broker funnels. Composes with G-002: a subshell targeting a *different* console needs no scoping (its terminal is its own); this goal covers the common shared-console case. diff --git a/goals/G-010-subshell-tree-navigation.md b/goals/G-010-subshell-tree-navigation.md index 90dbed9c..35693d37 100644 --- a/goals/G-010-subshell-tree-navigation.md +++ b/goals/G-010-subshell-tree-navigation.md @@ -49,3 +49,4 @@ escape hatch. - Suspend/resume semantics for in-flight commands in a suspended subshell (block? continue headless with output buffered?) is an implementation-time decision to be recorded here when made; the acceptance only requires suspended subshells to be listable and resumable. +- Archived-goal references in this file: G-007 achieved 2026-07-05 (goals/archive/G-007-console-location-transparency.md). diff --git a/goals/G-011-console-stderr-semantics.md b/goals/G-011-console-stderr-semantics.md index 6acb0f72..0f568ba9 100644 --- a/goals/G-011-console-stderr-semantics.md +++ b/goals/G-011-console-stderr-semantics.md @@ -106,3 +106,4 @@ untouched. - **Not in scope.** Channel transforms/filtering on err (shellfilter stacks), a separate err reader, and any change to shellrun's process-layer stdout/stderr handling - this goal defines the console-side slot they can target. +- Archived-goal references in this file: G-001 achieved 2026-07-11 (goals/archive/G-001-pluggable-console-backends.md);G-007 achieved 2026-07-05 (goals/archive/G-007-console-location-transparency.md). diff --git a/goals/G-012-template-payload-safety.md b/goals/G-012-template-payload-safety.md index b2afcc31..d3051392 100644 --- a/goals/G-012-template-payload-safety.md +++ b/goals/G-012-template-payload-safety.md @@ -87,3 +87,6 @@ payload drift is unmanaged. - Verification tie-in: the dual-VCS sync checks in `.fossil-settings/AGENTS.md` double as a regression detector for this class - after this goal, the "git-tracked invisible to fossil" comparison should show no template-payload entries. +- G-062 (archived) recorded a follow-on in this territory: seeding LICENSE.txt into generated + project layouts (deliberately excluded from G-062's acceptance because src/project_layouts + sync is restricted) - see goals/archive/G-062-project-license-file.md. diff --git a/goals/G-013-raw-mode-default.md b/goals/G-013-raw-mode-default.md index 484d65cc..6c13709e 100644 --- a/goals/G-013-raw-mode-default.md +++ b/goals/G-013-raw-mode-default.md @@ -30,8 +30,8 @@ the line-mode type-ahead-loss window during terminal-query raw cycling gate. Its startup default should ultimately come from stored configuration via ::punk::config (see G-014) - toml-backed, independently configurable per named - subshell - with off as the built-in fallback. Longer term, once the console - framework is more complete (G-001 backends), this live view could be streamed + subshell - with off as the built-in fallback. Longer term, with the G-001 backend + framework in place (achieved 2026-07-11), this live view could be streamed off-console instead - e.g. over udp to a monitoring app, or to a tk text-widget system acting as a pseudo terminal. 3. **console_debugview** (repl ~1976) - already gated (debug_repl > 0). diff --git a/goals/G-014-punk-config-toml.md b/goals/G-014-punk-config-toml.md index 4394184b..67bdde27 100644 --- a/goals/G-014-punk-config-toml.md +++ b/goals/G-014-punk-config-toml.md @@ -60,3 +60,7 @@ tomlish be re-vendored before punk::config implementation proceeds. - Reusing Tcl-native config formats (plain dict/script files) - rejected: toml is already the declared format in punk::config 0.1 and is editable/diffable by users without Tcl knowledge. + +## Notes + +- Archived-goal references in this file: G-007 achieved 2026-07-05 (goals/archive/G-007-console-location-transparency.md). diff --git a/goals/G-016-projects-work-git-discovery.md b/goals/G-016-projects-work-git-discovery.md index 6c717825..dc97e617 100644 --- a/goals/G-016-projects-work-git-discovery.md +++ b/goals/G-016-projects-work-git-discovery.md @@ -84,6 +84,7 @@ Result-shape considerations: prevention side (scratch `FOSSIL_HOME` for throwaway repos) is recorded in root AGENTS.md User Preferences. - Depends on nothing, but its value to agents is realised through G-015 - (reliable piped invocation) and G-017 (agent guidance documenting the call). + (reliable piped invocation - achieved 2026-07-07) and G-017 (agent guidance documenting the call). - The `-cd` / `-detail` options and case-insensitive glob behaviour of the existing command are contracts to preserve. +- Archived-goal references in this file: G-049 achieved 2026-07-10 (goals/archive/G-049-punkargs-parse-status-model.md). diff --git a/goals/G-017-agent-project-discovery.md b/goals/G-017-agent-project-discovery.md index 47f6bdc7..0df62a92 100644 --- a/goals/G-017-agent-project-discovery.md +++ b/goals/G-017-agent-project-discovery.md @@ -2,5 +2,5 @@ Status: proposed Scope: AGENTS.md (root) or a child doc it indexes (guidance content only - no code) -Goal: once G-015 makes piped script calls reliable, repository guidance directs agents asked to locate another local project to query it via a piped `projects.work` call to a punk executable instead of grepping/globbing the wider filesystem. -Acceptance: root AGENTS.md (or a child doc indexed from it) records the exact recommended invocation - executable, subcommand, glob usage, and `-return json` as the parse target with its record fields - and states when filesystem scanning remains appropriate (projects not registered in any discovery source); the guidance is added only after G-015 is achieved (and notes the fossil-only limitation until G-016); following the documented pattern, an agent locates a named sibling project's checkout dir with a single piped call. +Goal: now that G-015 (achieved 2026-07-07 - see goals/archive/G-015-script-subcommand-piped-stdin.md) makes piped script calls reliable, repository guidance directs agents asked to locate another local project to query it via a piped `projects.work` call to a punk executable instead of grepping/globbing the wider filesystem. +Acceptance: root AGENTS.md (or a child doc indexed from it) records the exact recommended invocation - executable, subcommand, glob usage, and `-return json` as the parse target with its record fields - and states when filesystem scanning remains appropriate (projects not registered in any discovery source); the guidance is added only after G-015 is achieved (satisfied - G-015 achieved 2026-07-07; the fossil-only limitation note is still required until G-016); following the documented pattern, an agent locates a named sibling project's checkout dir with a single piped call. diff --git a/goals/G-020-screencap-input-module.md b/goals/G-020-screencap-input-module.md index 6bba4762..8f7111b8 100644 --- a/goals/G-020-screencap-input-module.md +++ b/goals/G-020-screencap-input-module.md @@ -92,6 +92,7 @@ the module is a separate development, not a refactor of it. - Related: G-018 (kit composition; Tk as loadable package, no wish binaries), G-019 (a trimmed capture-capable executable is a plausible scan target), G-021 (agent-facing surface over this module), G-001 (backend plugin pattern). +- Archived-goal references in this file: G-001 achieved 2026-07-11 (goals/archive/G-001-pluggable-console-backends.md); G-015 achieved 2026-07-07 (goals/archive/G-015-script-subcommand-piped-stdin.md). ## Additional driving use case: repl interactive-behaviour verification (2026-07-11) diff --git a/goals/G-021-agent-visual-verification.md b/goals/G-021-agent-visual-verification.md index 50a5f97d..60775899 100644 --- a/goals/G-021-agent-visual-verification.md +++ b/goals/G-021-agent-visual-verification.md @@ -49,7 +49,7 @@ tool calls during a session. ## Notes -- Depends on G-020 (mechanism) and G-015 (reliable piped calls); guidance +- Depends on G-020 (mechanism) and G-015 (reliable piped calls - achieved 2026-07-07); guidance placement follows G-017. - Image handoff sizing: agents ingest images with dimension/size limits; snapshot operations should support downscale/crop options eventually - diff --git a/goals/G-022-fossil-rename-punkshell.md b/goals/G-022-fossil-rename-punkshell.md index b32f0549..549451e4 100644 --- a/goals/G-022-fossil-rename-punkshell.md +++ b/goals/G-022-fossil-rename-punkshell.md @@ -65,8 +65,9 @@ phantoms surface directly in agent search results. ## Notes -- Dependent on G-015 (reliable piped script calls) for the application step; - the capability work itself has no dependency and can proceed earlier. +- Dependent on G-015 (reliable piped script calls) for the application step - + satisfied: G-015 achieved 2026-07-07, see + goals/archive/G-015-script-subcommand-piped-stdin.md. - The working-tree directory name (C:/repo/jn/shellspy) is out of scope - fossil does not require checkout dirs to match the project name. - Other checkouts of shellspy.fossil (e.g. a shellspy_copy working tree, if diff --git a/goals/G-024-mapvfs-toml.md b/goals/G-024-mapvfs-toml.md index 233da16f..438d7b9d 100644 --- a/goals/G-024-mapvfs-toml.md +++ b/goals/G-024-mapvfs-toml.md @@ -64,3 +64,8 @@ with the G-014 direction of toml + tomlish for declared configuration. punk::config consumption; build-tooling use here can proceed with tomlish as-is), G-012 (layout template refresh, if layout copies of runtime config are affected). +- G-037 (archived) named this file as the natural home for per-kit vendorlib payload + declarations, and recorded that vendorlib and kit vfs trees have drifted in BOTH directions + (vendorlib newer for udp, older for twapi) so any sync declaration needs explicit + direction/authority semantics, not "copy newer over older" - see + goals/archive/G-037-vendorlib-vfs-propagation.md. diff --git a/goals/G-025-exe-selfreport.md b/goals/G-025-exe-selfreport.md index a6cd0cb4..aac66714 100644 --- a/goals/G-025-exe-selfreport.md +++ b/goals/G-025-exe-selfreport.md @@ -81,3 +81,4 @@ Edge cases driving the acceptance clauses: - Related: G-023 (version-named binaries this complements), G-024 (build mapping that will drive stamping inputs), G-015 (piped invocation of the subcommand), G-014 (punkproject.toml reading may share tomlish plumbing). +- Archived-goal references in this file: G-007 achieved 2026-07-05 (goals/archive/G-007-console-location-transparency.md);G-015 achieved 2026-07-07 (goals/archive/G-015-script-subcommand-piped-stdin.md). diff --git a/goals/G-027-derived-project-pull-updates.md b/goals/G-027-derived-project-pull-updates.md index e434fe15..dbd607a7 100644 --- a/goals/G-027-derived-project-pull-updates.md +++ b/goals/G-027-derived-project-pull-updates.md @@ -118,3 +118,6 @@ What a pull may touch splits by ownership, not by file type: and the 2026-07-06 manual recovery are the concrete push-model precedents to test the pull against: a scratch project seeded at an old layout vintage should be fully recoverable by one pull. +- G-062 (archived) recorded a follow-on relevant here: seeding LICENSE.txt into generated + project layouts and pulling it into derived projects (deliberately excluded from G-062's + acceptance) - see goals/archive/G-062-project-license-file.md. diff --git a/goals/G-030-maketcl-punkargs.md b/goals/G-030-maketcl-punkargs.md index f8fc90ea..93bd9890 100644 --- a/goals/G-030-maketcl-punkargs.md +++ b/goals/G-030-maketcl-punkargs.md @@ -74,3 +74,4 @@ usage as its first surface. - Observation parked here from the same session: runtests/make.tcl-adjacent tooling that returns result dicts should document their key shape (see the runx -tcl exitcode note in G-015's detail). +- Archived-goal references in this file: G-015 achieved 2026-07-07 (goals/archive/G-015-script-subcommand-piped-stdin.md). diff --git a/goals/G-031-componentized-kit-boot.md b/goals/G-031-componentized-kit-boot.md index 1e78b9c6..4e17fe36 100644 --- a/goals/G-031-componentized-kit-boot.md +++ b/goals/G-031-componentized-kit-boot.md @@ -71,10 +71,11 @@ permanently own - a thousand lines of boot code. ## Notes -- Sequencing with G-015: the script-subcommand work touches the same dispatch - tail. Either order works, but whichever lands second must preserve the - other's behaviour; if G-015 proceeds first on the monolith, its dispatch - logic moves into the boot core here. +- Sequencing with G-015: resolved - G-015 proceeded first on the monolith + (achieved 2026-07-07 as the dedicated app-punkscript package, see + goals/archive/G-015-script-subcommand-piped-stdin.md), so its dispatch + logic moves into the boot core here and this goal must preserve the + script subcommand's behaviour. - Related: G-027 (ownership + pull channel this is designed for), G-025 (boot-core vintage reporting), G-032 (punk::args-defined dispatch built on the registration model), G-012 (layout payload hygiene), G-018 (plain tclsh diff --git a/goals/G-032-launcher-punkargs.md b/goals/G-032-launcher-punkargs.md index 3316d863..c8ef98e4 100644 --- a/goals/G-032-launcher-punkargs.md +++ b/goals/G-032-launcher-punkargs.md @@ -62,3 +62,4 @@ in `-help` by registration alone. natural first parsed subcommand; exit-code semantics), G-025 (version-report subcommand born punk::args-defined), G-013 (the debugrepl activation review mentions proper-command conversions that would slot into the same pattern). +- Archived-goal references in this file: G-015 achieved 2026-07-07 (goals/archive/G-015-script-subcommand-piped-stdin.md). diff --git a/goals/G-033-proj-mode-cwd-project.md b/goals/G-033-proj-mode-cwd-project.md index 113567a0..a5c959f0 100644 --- a/goals/G-033-proj-mode-cwd-project.md +++ b/goals/G-033-proj-mode-cwd-project.md @@ -170,3 +170,4 @@ ships with the prefix, not before): packagemode help text above), G-015 (`proj:... script` also benefits), G-027 (if a universal project marker is ever seeded, proj could prefer it over the structural VCS heuristic). +- Archived-goal references in this file: G-015 achieved 2026-07-07 (goals/archive/G-015-script-subcommand-piped-stdin.md). diff --git a/goals/G-038-piped-session-continuity.md b/goals/G-038-piped-session-continuity.md index 0d681db4..fccf785d 100644 --- a/goals/G-038-piped-session-continuity.md +++ b/goals/G-038-piped-session-continuity.md @@ -181,3 +181,4 @@ object's channels). State observed pre-fix, for reference: repl thread post-rest `stdin` eof=1 (the exhausted pipe) alongside the new `file...` CONIN$ channel; the code interp's stdin is a live console channel (utf-16, -inputmode present); anchored instances known to the repl thread: `default` (anchored to the dead pair). +- Archived-goal references in this file: G-001 achieved 2026-07-11 (goals/archive/G-001-pluggable-console-backends.md);G-007 achieved 2026-07-05 (goals/archive/G-007-console-location-transparency.md);G-015 achieved 2026-07-07 (goals/archive/G-015-script-subcommand-piped-stdin.md);G-036 achieved 2026-07-08 (goals/archive/G-036-tcl9-udp-console-worker-wedge.md). diff --git a/goals/G-039-orphan-console-spin.md b/goals/G-039-orphan-console-spin.md index c5d2fe4e..da78b19d 100644 --- a/goals/G-039-orphan-console-spin.md +++ b/goals/G-039-orphan-console-spin.md @@ -46,3 +46,4 @@ punk::console query/read helpers. same neighbourhood). - Harness hygiene until fixed: verify no stray punk902z processes before scoring any liveness-based test run. +- Archived-goal references in this file: G-036 achieved 2026-07-08 (goals/archive/G-036-tcl9-udp-console-worker-wedge.md). diff --git a/goals/G-041-punkargs-form-matching.md b/goals/G-041-punkargs-form-matching.md index 6bcacecf..d7971ce8 100644 --- a/goals/G-041-punkargs-form-matching.md +++ b/goals/G-041-punkargs-form-matching.md @@ -84,3 +84,4 @@ when shaping step 1. assignment (punk/args ~l.6186; its happy-path twin was already commented). Fixed 2026-07-08 (punk::args 0.2.3) - noted here because form-attempt logic will exercise that failure path heavily. +- Archived-goal references in this file: G-040 achieved 2026-07-08 (goals/archive/G-040-punkargs-choicealiases.md). diff --git a/goals/G-042-subshell-help-topics.md b/goals/G-042-subshell-help-topics.md index b5222746..f2f14e99 100644 --- a/goals/G-042-subshell-help-topics.md +++ b/goals/G-042-subshell-help-topics.md @@ -48,9 +48,8 @@ explicit rather than accidental. escape hatch for a shadowed command name is 'i ' / 's ' (the first-class command-help route) - document it where the topic set is presented ('help topics' footer or the ::punk::help -help text). -4. Display: alias folding for declared topics inherits whatever G-040 lands - (-choicealiases); until then aliases appear as separate documented choices, as the - built-ins do today. +4. Display: alias folding for declared topics inherits G-040's -choicealiases + (achieved 2026-07-08 - see goals/archive/G-040-punkargs-choicealiases.md). ## Relationship to the intended plugin facility (code review 2026-07-08) diff --git a/goals/G-044-repl-command-completion.md b/goals/G-044-repl-command-completion.md index b4d7c463..a29707b1 100644 --- a/goals/G-044-repl-command-completion.md +++ b/goals/G-044-repl-command-completion.md @@ -38,7 +38,7 @@ arginfo principle: introspection must not run commands to elicit usage). plus the synopsis/form information for the current position. Sources: punk::ns::cmdinfo for the command-word path, punk::args::get_spec for the argument position. Choice-word matching must reuse the parser's resolution rules (the shared - choice-resolution helper planned in G-040 is the natural common code; prefix + choice-resolution helper from G-040 (achieved 2026-07-08) is the natural common code; prefix highlighting from the usage renderer already computes minimal prefixes). Form handling: before G-041, enumerate all forms' next-position candidates (union) and show all/form-0 synopses with the limitation noted; when G-041's candidacy API @@ -86,6 +86,7 @@ arginfo principle: introspection must not run commands to elicit usage). src/tests/modules/punk/ns/testsuites/ns/cmdflow.test (2026-07-08), including ensemble -parameters handling; the choice semantics by src/tests/modules/punk/args/testsuites/args/choices.test; forms by forms.test. +- Archived-goal references in this file: G-001 achieved 2026-07-11 (goals/archive/G-001-pluggable-console-backends.md); G-040 achieved 2026-07-08 (goals/archive/G-040-punkargs-choicealiases.md). ## Repl behaviour preserve-list + testability findings (2026-07-11, user-directed - pre-refactor ordering) diff --git a/goals/G-045-punkargs-authoring-ergonomics.md b/goals/G-045-punkargs-authoring-ergonomics.md index dfbe6a05..e3a080c4 100644 --- a/goals/G-045-punkargs-authoring-ergonomics.md +++ b/goals/G-045-punkargs-authoring-ergonomics.md @@ -94,3 +94,4 @@ punk::imap4's {\Deleted}/{$MDNSent} choice values) have them stated, not just te - Session records 2026-07-09: probe scripts renderprobe*.tcl (scratchpad), the user's experimental define_docs hack (uncommitted punk.tm working-tree diff at the time of drafting - superseded by this goal when implemented). +- Archived-goal references in this file: G-046 achieved 2026-07-10 (goals/archive/G-046-punkargs-deferred-help-and-fixes.md). diff --git a/goals/G-050-synopsis-validity-marking.md b/goals/G-050-synopsis-validity-marking.md index 8821197f..40ca81ac 100644 --- a/goals/G-050-synopsis-validity-marking.md +++ b/goals/G-050-synopsis-validity-marking.md @@ -37,7 +37,7 @@ string"). ## Notes -- Depends on G-049 (status structure). G-044's hint display is a future consumer of the +- Depends on G-049 (status structure) - satisfied: achieved 2026-07-10, see goals/archive/G-049-punkargs-parse-status-model.md. G-044's hint display is a future consumer of the same API - keep the marking function reusable outside synopsis/cmdhelp rendering. - Existing string-shape tests: args testsuite synopsis.test and the installed test::punk::args synopsis tests ("must be no leading space" convention) - marking must diff --git a/goals/G-052-oo-method-autodef.md b/goals/G-052-oo-method-autodef.md index 49682716..4741452f 100644 --- a/goals/G-052-oo-method-autodef.md +++ b/goals/G-052-oo-method-autodef.md @@ -53,3 +53,4 @@ just not wired up as a general method-level (autodef) generation step in the doc - Filters, private methods and `unknown` handlers are marked in choiceinfo today but out of scope for autodef generation. - Coordinate the cmdtype reported for method resolutions with G-051's doconly decision. +- Archived-goal references in this file: G-040 achieved 2026-07-08 (goals/archive/G-040-punkargs-choicealiases.md). diff --git a/goals/G-053-punkargs-multiple-ranges.md b/goals/G-053-punkargs-multiple-ranges.md index 4a4312ac..dfd25e7c 100644 --- a/goals/G-053-punkargs-multiple-ranges.md +++ b/goals/G-053-punkargs-multiple-ranges.md @@ -66,3 +66,4 @@ rendering gain meaningful bounded-repetition forms (e.g. "0-1", "2-4"). canonicalization must not regress the hot path). - The runtests `-include-paths` fix (repeatable, accumulate, single-list form still accepted) shipped independently on 2026-07-10 and does not depend on this goal. +- Archived-goal references in this file: G-046 achieved 2026-07-10 (goals/archive/G-046-punkargs-deferred-help-and-fixes.md). diff --git a/goals/G-055-tclcore-regen-workflow.md b/goals/G-055-tclcore-regen-workflow.md index 609fb9fd..b7a41cfd 100644 --- a/goals/G-055-tclcore-regen-workflow.md +++ b/goals/G-055-tclcore-regen-workflow.md @@ -90,3 +90,4 @@ other commands including the multi-form ::after. side-effect-free invocations of pure builtins (deliberately-invalid calls harvesting error metadata). This does not relax cmdhelp's rule of never calling arbitrary commands to elicit usage at query time. +- Archived-goal references in this file: G-049 achieved 2026-07-10 (goals/archive/G-049-punkargs-parse-status-model.md);G-054 achieved 2026-07-11 (goals/archive/G-054-tclcore-stringis-harvest.md). diff --git a/goals/G-056-punkargs-word-wrapping.md b/goals/G-056-punkargs-word-wrapping.md index 834a17c5..6385b16c 100644 --- a/goals/G-056-punkargs-word-wrapping.md +++ b/goals/G-056-punkargs-word-wrapping.md @@ -56,3 +56,4 @@ the current table -maxwidth 80 default; an explicit width option overrides both. those, not just the table path. - Characterization first: pin current no-wrap rendering of an over-width line (overflow behaviour) before changing it, per the usual GAP-pin workflow. +- Archived-goal references in this file: G-046 achieved 2026-07-10 (goals/archive/G-046-punkargs-deferred-help-and-fixes.md). diff --git a/goals/G-060-qemu-test-matrix.md b/goals/G-060-qemu-test-matrix.md index 81bc6b79..3b8e5202 100644 --- a/goals/G-060-qemu-test-matrix.md +++ b/goals/G-060-qemu-test-matrix.md @@ -61,3 +61,4 @@ direction rather than a new ad-hoc location. exercises runtime.cmd's unix payload for real), [[G-059]] (contract sibling). - Performance expectations should stay modest (emulated arm will be slow); the matrix is for correctness verification, not speed benchmarking. +- Archived-goal references in this file: G-059 achieved 2026-07-11 (goals/archive/G-059-wsl-test-driving.md). diff --git a/goals/G-061-pseudoconsole-expect.md b/goals/G-061-pseudoconsole-expect.md index c773182c..047a0f23 100644 --- a/goals/G-061-pseudoconsole-expect.md +++ b/goals/G-061-pseudoconsole-expect.md @@ -77,3 +77,4 @@ expect-like primitives over a REAL pseudo-terminal: - ConPTY availability gates the windows side to Win10 1809+ (fine for punkshell's supported baseline); the capability probe should verify actual ConPTY function, not windows version. +- Archived-goal references in this file: G-001 achieved 2026-07-11 (goals/archive/G-001-pluggable-console-backends.md);G-059 achieved 2026-07-11 (goals/archive/G-059-wsl-test-driving.md). diff --git a/goals/G-063-package-license-tracking.md b/goals/G-063-package-license-tracking.md index 0580fbf7..a3ff706c 100644 --- a/goals/G-063-package-license-tracking.md +++ b/goals/G-063-package-license-tracking.md @@ -32,3 +32,4 @@ it auditable per package. - Related: G-026 (vendorupdate is the natural hook for capturing vendored license provenance), G-060 (recorded GPL-safe posture), G-062 (project's own license id), G-064 (lib.search as the interactive surface for these indications). +- Archived-goal references in this file: G-062 achieved 2026-07-11 (goals/archive/G-062-project-license-file.md). diff --git a/goals/archive/G-015-script-subcommand-piped-stdin.md b/goals/archive/G-015-script-subcommand-piped-stdin.md index d4561f0f..33708e4e 100644 --- a/goals/archive/G-015-script-subcommand-piped-stdin.md +++ b/goals/archive/G-015-script-subcommand-piped-stdin.md @@ -95,6 +95,17 @@ punk_main.tcl's `punk` subcommand case). ## Notes +- Achieved-status detail (restored 2026-07-11; this text originally rode the + Status: line as a parenthetical and was dropped when the 2026-07-11 two-tier + index restructure normalised detail-file Status lines to the bare index form): + implemented as src/lib/app-punkscript; verified on punk902z/tcl9 and + punksys/tcl8.6 kits: piped success/error/exit-code cases, file form with args + and stdin passthrough, and the motivating `dev projects.work *tomlish*` + one-liner - table emitted, exit 0, no boilerplate. Stdin form additionally + echoes the script's final result when non-empty, giving return-value commands + one-liner ergonomics; file form keeps pure script semantics. + Terminal-stdin-with-no-args yields a usage error by design - spot-check from a + real console typed session remains a manual item. - Result-shape observation (2026-07-07): `shellrun::runx -tcl` returns a dict keyed {result stdout stderr} with NO exitcode key, unlike the exec-mode result (exitinfo with exitcode) - callers doing `dict get $result exitcode` diff --git a/goals/G-062-project-license-file.md b/goals/archive/G-062-project-license-file.md similarity index 54% rename from goals/G-062-project-license-file.md rename to goals/archive/G-062-project-license-file.md index 1d7b382a..6f987487 100644 --- a/goals/G-062-project-license-file.md +++ b/goals/archive/G-062-project-license-file.md @@ -1,6 +1,6 @@ # G-062 Canonical project license: BSD-2-Clause LICENSE file with SPDX-identified references -Status: proposed +Status: achieved 2026-07-11 Scope: LICENSE.txt (new, repo root), README.md, punkproject.toml ([project] license field), AGENTS.md (Repo-wide Notes license mention) Goal: the repository declares exactly one canonical license: a root LICENSE.txt containing the verbatim BSD-2-Clause text, with README.md and root AGENTS.md naming the license by its SPDX identifier and pointing at LICENSE.txt, and punkproject.toml carrying the identifier machine-readably so tooling (the G-063 audit, derived-project seeding) can read the project license without parsing prose. Acceptance: LICENSE.txt exists at the repo root containing the standard BSD-2-Clause text with a real copyright line; README.md names BSD-2-Clause and points at LICENSE.txt; root AGENTS.md Repo-wide Notes names the license precisely; punkproject.toml [project] carries license = "BSD-2-Clause"; a repo-sweep for top-level license claims finds none contradicting it (sweep result recorded here). @@ -14,8 +14,21 @@ a variant is not a specific license; BSD-2-Clause is the chosen variant ## Notes -- Copyright line content (holder name, year range) to be confirmed with the user at - write time. +- Copyright holder: Julian Marcel Noble; year range: 2023-2026 (user-confirmed + 2026-07-11). - Seeding LICENSE.txt into generated project layouts is a natural follow-on but is deliberately not part of this goal's acceptance (src/project_layouts sync is restricted; see G-012/G-027 territory). + +## Sweep result (2026-07-11) + +Repo-sweep for top-level license claims found none contradicting BSD-2-Clause: + +- `README.md`, `AGENTS.md`, `punkproject.toml` — now explicitly BSD-2-Clause (this goal's edits). +- `src/embedded/md/doc/files/punk/_module_cap-0.1.0.tm.md` — "Copyright © 2023 JMNoble - BSD licensed" is a module-level generated doc, not a project-level claim; the module author's own license indication, not the project's. +- `src/vfs/punk9win.vfs/lib/materialicons0.2/README.md` — "License: BSD" — vendored library (materialicons), not the project license. +- `src/vfs/*/tdot0.3.1/tdot.md` — "MIT License" — vendored library (tdot), its own license. +- `src/vfs/critclxxx.vfs/embedded/md/files/critcl_license.md` — "All packages are under the BSD license" — vendored critcl documentation, not the project's claim. +- Goal files (G-060, G-063, G-064) reference "license" in their contracts — descriptive, not claiming a project license. + +No contradictions. The project-level license declaration is unambiguous: BSD-2-Clause via `LICENSE.txt`, `README.md`, `AGENTS.md`, and `punkproject.toml`. diff --git a/punkproject.toml b/punkproject.toml index df52aa47..dfbf51e0 100644 --- a/punkproject.toml +++ b/punkproject.toml @@ -1,3 +1,4 @@ [project] name = "punkshell" -version = "0.12.0" +version = "0.12.1" +license = "BSD-2-Clause" diff --git a/scriptlib/developer/goals_lint.tcl b/scriptlib/developer/goals_lint.tcl new file mode 100644 index 00000000..0ac96e11 --- /dev/null +++ b/scriptlib/developer/goals_lint.tcl @@ -0,0 +1,218 @@ +#!/usr/bin/env tclsh +# goals_lint.tcl - lint the two-tier goals documentation +# (root GOALS.md / GOALS-archive.md indexes + goals/ / goals/archive/ detail files) +# +# Validates the contracts declared in goals/AGENTS.md and root AGENTS.md: +# - detail-file header grammar: '# G- ' then a blank line, then +# Status:/Scope:/Goal:/Acceptance: exactly once each, in order, one line each, +# before any '## section'; no prose riding a header field +# - Status: values are exactly one of proposed|active|abandoned|superseded or +# 'achieved YYYY-MM-DD' +# - active-tree detail files are not 'achieved'; archive detail files are +# - no orphans: every goals/*.md detail file has a GOALS.md index entry and vice +# versa; every goals/archive/*.md file has a GOALS-archive.md record and vice versa +# - Status:/Scope: mirror lines in detail files match the owning index entry +# +# Plain tclsh (8.6+ or 9), no package dependencies - runnable from any checkout: +# tclsh scriptlib/developer/goals_lint.tcl [repo-root] +# Exit 0 when clean; exit 1 with one 'path: problem' line per finding. + +set root [expr {$argc >= 1 ? [lindex $argv 0] : [file dirname [file dirname [file dirname [file normalize [info script]]]]]}] +if {![file isfile [file join $root GOALS.md]] || ![file isdir [file join $root goals]]} { + puts stderr "goals_lint: '$root' does not look like the punkshell repo root (need GOALS.md and goals/)" + exit 2 +} + +set findings {} +proc flag {path msg} { + global findings + lappend findings "$path: $msg" +} + +set status_re {^(proposed|active|abandoned|superseded|achieved \d{4}-\d{2}-\d{2})$} + +proc read_lines {path} { + set f [open $path r] + fconfigure $f -encoding utf-8 + set lines [split [read $f] \n] + close $f + return $lines +} + +# --- parse an index file (GOALS.md or GOALS-archive.md) --------------------- +# returns dict: id -> {status <s> title <t> scope <scope-or-empty>} +proc parse_index {path} { + global status_re + set entries [dict create] + set relpath [file tail $path] + set curid "" + foreach line [read_lines $path] { + if {[regexp {^### G-(\d+) \[([^\]]*)\] (.*)$} $line -> id status title]} { + set curid $id + if {[dict exists $entries $id]} { + flag $relpath "duplicate index entry G-$id" + } + if {![regexp $status_re $status]} { + flag $relpath "G-$id: bad status '\[$status\]' (want proposed|active|abandoned|superseded|achieved YYYY-MM-DD)" + } + dict set entries $id [dict create status $status title $title scope ""] + } elseif {[regexp {^### } $line]} { + set curid "" + } elseif {$curid ne "" && [regexp {^Scope: (.*)$} $line -> scope]} { + dict set entries $curid scope $scope + } + } + return $entries +} + +# --- lint one detail file ---------------------------------------------------- +# returns dict {id <id> status <s> scope <s>} (empty strings when unparseable) +proc lint_detail {path relpath} { + global status_re + set lines [read_lines $path] + set fname [file tail $path] + set result [dict create id "" status "" scope ""] + + if {![regexp {^G-(\d+)-[a-z0-9-]+\.md$} $fname -> fid]} { + flag $relpath "filename does not match G-<id>-<slug>.md" + set fid "" + } + dict set result id $fid + + if {![regexp {^# G-(\d+) .+$} [lindex $lines 0] -> hid]} { + flag $relpath "line 1 is not '# G-<id> <title>'" + set hid "" + } + if {$fid ne "" && $hid ne "" && $hid ne $fid} { + flag $relpath "title-line id G-$hid does not match filename id G-$fid" + } + if {[lindex $lines 1] ne ""} { + flag $relpath "line 2 is not blank" + } + + # header fields: Status/Scope/Goal/Acceptance exactly once each, in order, + # before the first '## ' section + set want {Status Scope Goal Acceptance} + set found [dict create] + set order {} + set i 2 + foreach line [lrange $lines 2 end] { + incr i + if {[regexp {^## } $line]} break + if {[regexp {^(Status|Scope|Goal|Acceptance): ?(.*)$} $line -> field value]} { + if {[dict exists $found $field]} { + flag $relpath "duplicate header field '$field:' (line $i)" + } else { + dict set found $field $value + lappend order $field + } + if {$value eq ""} { + flag $relpath "empty header field '$field:' (line $i)" + } + } + } + foreach field $want { + if {![dict exists $found $field]} { + flag $relpath "missing header field '$field:'" + } + } + if {[llength $order] == 4 && $order ne $want} { + flag $relpath "header fields out of order ([join $order /] - want [join $want /])" + } + + if {[dict exists $found Status]} { + set status [dict get $found Status] + dict set result status $status + if {![regexp $status_re $status]} { + flag $relpath "bad Status line 'Status: $status' - must be exactly proposed|active|abandoned|superseded or 'achieved YYYY-MM-DD' with no additional prose (verification evidence belongs in ## Progress / ## Notes)" + } + } + if {[dict exists $found Scope]} { + dict set result scope [dict get $found Scope] + } + return $result +} + +# --- run ---------------------------------------------------------------------- +set active_index [parse_index [file join $root GOALS.md]] +set archive_index [parse_index [file join $root GOALS-archive.md]] + +foreach {dir index indexname achieved_expected} [list \ + goals $active_index GOALS.md 0 \ + [file join goals archive] $archive_index GOALS-archive.md 1] { + set seen [dict create] + foreach path [lsort [glob -nocomplain -directory [file join $root $dir] G-*.md]] { + set relpath [string map {\\ /} [file join $dir [file tail $path]]] + set info [lint_detail $path $relpath] + set id [dict get $info id] + if {$id eq ""} continue + dict set seen $id 1 + set achieved [string match "achieved *" [dict get $info status]] + if {$achieved_expected && !$achieved && [dict get $info status] ne ""} { + flag $relpath "archived detail file Status is '[dict get $info status]' - archive/ holds achieved goals only" + } elseif {!$achieved_expected && $achieved} { + flag $relpath "achieved goal still in goals/ - the achieved flip includes archiving (move to goals/archive/, record in GOALS-archive.md)" + } + if {![dict exists $index $id]} { + flag $relpath "orphan detail file - no G-$id entry in $indexname" + continue + } + set entry [dict get $index $id] + if {[dict get $info status] ne "" && [dict get $info status] ne [dict get $entry status]} { + flag $relpath "Status mirror '[dict get $info status]' disagrees with $indexname '\[[dict get $entry status]\]' (index wins)" + } + if {[dict get $info scope] ne "" && [dict get $entry scope] ne "" \ + && [dict get $info scope] ne [dict get $entry scope]} { + flag $relpath "Scope mirror disagrees with $indexname (index wins)" + } + } + foreach id [dict keys $index] { + if {![dict exists $seen $id]} { + flag $indexname "G-$id has no detail file in $dir/" + } + } +} + +# --- informational: candidate stale references to archived goals --------------- +# An active detail file mentioning an archived goal with no achieved/archive/landed +# marker on ANY of the mentioning lines has likely missed the archive-time reference +# sweep (goals/AGENTS.md Archive rules) - a reader cannot tell the referenced goal is +# done. One marked mention per file suffices; pure-history mentions on other lines +# are fine. Heuristic - reported as warnings, never fatal. +set warnings {} +foreach path [lsort [glob -nocomplain -directory [file join $root goals] G-*.md]] { + set relpath goals/[file tail $path] + set mentioned [dict create] ;# id -> 1 when any mentioning line carries a marker + set lines [read_lines $path] + set n [llength $lines] + for {set i 0} {$i < $n} {incr i} { + set line [lindex $lines $i] + # marker may sit on the mention line or a wrapped neighbour + set window "$line [lindex $lines [expr {$i-1}]] [lindex $lines [expr {$i+1}]]" + set marked [regexp -nocase {achieved|archive|landed} $window] + foreach id [regexp -all -inline {G-\d+} $line] { + set num [string range $id 2 end] + if {![dict exists $archive_index $num]} continue + if {$marked || ![dict exists $mentioned $num]} { + dict set mentioned $num $marked + } + } + } + dict for {num marked} $mentioned { + if {!$marked} { + lappend warnings "$relpath: references archived goal G-$num with no achieved/archive marker anywhere - reference sweep candidate (goals/AGENTS.md Archive rules)" + } + } +} + +if {[llength $warnings]} { + puts stderr "goals_lint: [llength $warnings] informational warning(s):" + puts stderr [join $warnings \n] +} +if {[llength $findings]} { + puts [join $findings \n] + puts stderr "goals_lint: [llength $findings] finding(s)" + exit 1 +} +puts "goals_lint: clean ([dict size $active_index] active-index goals, [dict size $archive_index] archived)" +exit 0