diff --git a/.agents/skills/ub-governance/SKILL.md b/.agents/skills/ub-governance/SKILL.md index c06afa9..7465aad 100644 --- a/.agents/skills/ub-governance/SKILL.md +++ b/.agents/skills/ub-governance/SKILL.md @@ -7,8 +7,8 @@ description : >- when the task involves governance modes, test-signal review, evidence levels, or decision-memory boundaries; or when they ask whether work needs governance escalation. Do not use it for workflow planning, framework - implementation, or this repository's repo-maintenance catalog, path, and - skill-integrity checks. + implementation, or the host repository's own maintenance catalog, path, + and skill-integrity checks. context : fork metadata : desktop-portfolio-help-topics : "overview,evidence,testing,repository,core,glossary,combos,invoke" @@ -152,7 +152,8 @@ If a trigger is not active, do not read the reference just because it exists. Use `testing mode`, apply the test-signal model, and treat likely `TG002` findings as blocking only when the suite is asserting interaction without externally observable outcome. -3. `Show me the repo-maintenance checks for README, AGENTS, and skill schema.` +3. `Show me the host repository's maintenance checks for README, AGENTS, + and skill schema.` Do not route that through governance. Those checks belong to the host repository's own maintenance/check surface. diff --git a/.agents/skills/ub-governance/references/decision-memory-and-claims.md b/.agents/skills/ub-governance/references/decision-memory-and-claims.md index 2ce0417..f9f0304 100644 --- a/.agents/skills/ub-governance/references/decision-memory-and-claims.md +++ b/.agents/skills/ub-governance/references/decision-memory-and-claims.md @@ -58,7 +58,11 @@ For Level 1 workflow-backed work: alternative was rejected, and what was explicitly deferred 3. sprint `evidence/` is the default evidence location for sprint-scoped proof and should stay closer to the work than initiative-root summaries -4. initiative-root `research/` and `exceptions/` are supporting surfaces, not +4. workflow research claim registries, when used by a host overlay, are + Level 1 workflow-native context records unless the decision is escalated to + repository-level governance or a blocking governance result depends on claim + confidence +5. initiative-root `research/` and `exceptions/` are supporting surfaces, not generic dumping grounds Ordinary initiative example: @@ -110,11 +114,13 @@ Typical triggers: 3. an exception or waiver remains acceptable only because supporting claims stay verified or explicitly bounded -Do not require claim-register work by default for: +Do not require governance claim-register work by default for: 1. ordinary Level 1 workflow-backed initiative records -2. descriptive examples or non-blocking explanatory prose -3. decisions that can be justified directly from deterministic artifacts +2. workflow-native research claim registries that only route discovery context + and do not support a blocking governance result +3. descriptive examples or non-blocking explanatory prose +4. decisions that can be justified directly from deterministic artifacts without claim confidence High-risk-governance example: diff --git a/.agents/skills/ub-governance/references/governance-commands.md b/.agents/skills/ub-governance/references/governance-commands.md index e76a379..a85623e 100644 --- a/.agents/skills/ub-governance/references/governance-commands.md +++ b/.agents/skills/ub-governance/references/governance-commands.md @@ -33,7 +33,7 @@ Operator intent: and bounded initiative `exceptions/` instead of invoking ADR machinery by default. 4. Repository-catalog, package-metadata, and skill-surface integrity scripts - are repo-maintenance tooling, not default governance commands. + are host-repository maintenance tooling, not default governance commands. Host-repository wrappers: @@ -42,10 +42,10 @@ Host-repository wrappers: 2. A host repository may expose a governance-regression wrapper through its own task runner. -Repo-local maintenance note: +Host-repository maintenance note: -1. Repo-maintenance wrappers belong to the host repository's own documented - maintenance/check surface. +1. Host-repository maintenance wrappers belong to the host repository's own + documented maintenance/check surface. 2. That surface is intentionally separate from the distributable governance command set carried by this skill. diff --git a/.agents/skills/ub-python/SKILL.md b/.agents/skills/ub-python/SKILL.md index f2662a8..2fa34de 100644 --- a/.agents/skills/ub-python/SKILL.md +++ b/.agents/skills/ub-python/SKILL.md @@ -128,6 +128,11 @@ Python lint config of its own. - Use `Protocol`, `Self`, `override`, `TypeGuard`, `TypeIs`, `Required`, `NotRequired`, `ReadOnly`, `TypeAliasType`, and `assert_never` when they improve correctness and refactor safety. - Do not invent custom typing compatibility shims when `typing_extensions` already provides the migration path. - Keep `Any` contained to boundaries and document why when unavoidable. +- In strict public or SDK-facing code, avoid ambiguous constructor overloads + such as `dict(mapping)` when the source type is a recursive alias or broad + `Mapping[str, JsonValue]`; prefer typed copy helpers, `{**mapping}`, or + explicit payload builders so Pyright/Pylance can prove the exact return + shape. ### Data Modeling and Validation diff --git a/.agents/skills/ub-python/references/python-standards.md b/.agents/skills/ub-python/references/python-standards.md index d574680..6e00594 100644 --- a/.agents/skills/ub-python/references/python-standards.md +++ b/.agents/skills/ub-python/references/python-standards.md @@ -56,6 +56,27 @@ specific host repository. - Prefer forward-compatible helpers and backports where they preserve the current repo floor while reducing future migration work, but do not emit syntax that the active runtime cannot parse. +- Avoid ambiguous overloaded constructors in strict public API code when the + source type is a recursive alias, broad mapping, or JSON-like boundary type. + `dict(mapping)` is valid Python, but type checkers may choose an overload + that widens or rejects recursive shapes such as `Mapping[str, JsonValue]`. + Prefer an explicit typed helper, `{**mapping}`, or a purpose-built payload + builder when exact `dict[str, T]` output matters. + +Example: + +```python +type JsonValue = None | bool | int | float | str | list["JsonValue"] | dict[str, "JsonValue"] +type JsonObject = Mapping[str, JsonValue] + + +def json_object_copy(value: JsonObject) -> dict[str, JsonValue]: + return {**value} +``` + +This is a strict-typing practice, not a Python runtime-version requirement: +`dict(mapping)` remains legal, but explicit copy helpers reduce Pyright, +Pylance, and basedpyright overload drift in SDK-facing code. ## 4. Data Modeling and Boundary Validation diff --git a/.agents/skills/ub-quality/references/freshness-portability.md b/.agents/skills/ub-quality/references/freshness-portability.md index 1245929..401d04b 100644 --- a/.agents/skills/ub-quality/references/freshness-portability.md +++ b/.agents/skills/ub-quality/references/freshness-portability.md @@ -83,3 +83,37 @@ Rules: 1. do not create a new blocker just because a skill is marked high-volatility 2. use freshness markers to prioritize review, not to halt unrelated work 3. tighten freshness only after the repository explicitly chooses stronger enforcement + +## Parallel Research Delegation + +When freshness, portability, donor comparison, official documentation review, +or analogous-system research has two or more independent read-heavy slices, +prefer explicit parallel delegation when the current agent runtime supports it. + +Portable trigger: + +1. each slice can be investigated without depending on another slice's result +2. the expected output is distilled evidence, not implementation +3. the sources or allowed paths can be bounded up front +4. the parent thread can verify anchors and reconcile conflicts + +Delegation contract: + +1. assign one subagent, background thread, or equivalent worker per slice +2. give each worker a bounded read-only task, allowed sources or paths, and + no-edit constraints +3. ask workers to return distilled findings with fact, inference, source, + implication, and rejected pattern when that shape fits the research +4. wait for all requested workers before consolidating +5. keep the parent agent accountable for source verification, conflict + reconciliation, and final recommendation + +Do not delegate when the task is single-threaded, the current runtime lacks a +safe subagent or background-thread surface, authorization boundaries are +unclear, or parallel work would mostly duplicate context. Use narrow +sequential passes instead. + +Do not use recursive fan-out unless the operator explicitly asks for it and the +runtime supports bounded recursion. For proprietary donors, use only authorized +paths, public docs, public license or README material, and observed behavior +the operator is allowed to inspect. diff --git a/.agents/skills/ub-workflow/SKILL.md b/.agents/skills/ub-workflow/SKILL.md index a737ae8..a5fec50 100644 --- a/.agents/skills/ub-workflow/SKILL.md +++ b/.agents/skills/ub-workflow/SKILL.md @@ -1,15 +1,13 @@ --- name: ub-workflow description: >- - Use this skill when the user wants to turn a rough idea, product problem, - engineering thread, or research track into the right planning surface: - direct bounded work, a lightweight spec, or a full initiative with PRD, - roadmap, and standalone resumable sprints; when the task involves initiative - scaffolding, lightweight-spec shaping, sprint planning, stop-resume - handoffs, final audit flow, or retained notes for multi-session work; or - when the user needs phased planning and context preservation for larger work. - Do not use it for governance-only questions that belong to ub-governance. -argument-hint: "overview | scaffold | spec | resume | prd | roadmap | sprint | audit | archive | what-next" + Use this skill when work needs durable planning, adaptive product slicing, + discovery before delivery, resumable sprint execution, wave or initiative + scaffolding, source-pack routing, closeout evidence, final audits, or + repeatable product-agile workflow structure. Do not use it for small direct + fixes that do not need a durable artifact, or for governance-only questions + that belong to ub-governance. +argument-hint: "overview | scaffold | source-atlas | wave | initiative | discovery | sprint | audit | archive | what-next" user-invocable: true disable-model-invocation: false --- @@ -18,314 +16,310 @@ disable-model-invocation: false ## Overview -Use this skill as the canonical workflow intake, initiative-planning, and -sprint-orchestration layer for work that is too large, risky, or stateful to -run safely from chat history alone. - -The default operating surface is `./.ub-workflows/` unless the host -intentionally chooses a different operations root. - -This skill owns three lanes only: - -1. direct bounded work when the work is a truly small fix or bounded task that - can be executed safely without a durable planning artifact -2. lightweight specs under `./.ub-workflows/specs/` when the work is still - bounded but now needs a durable contract for assumptions, scope, options, - validation, or a concrete execution plan -3. initiatives under `./.ub-workflows/initiatives/` when the work needs a - PRD, roadmap, and resumable sprint execution because it is multi-session, - staged, risky, or clearly cross-cutting - -If the work is a bounded one-off, prefer a lightweight spec. -If the work is multi-session, cross-cutting, risky, or needs staged delivery, -use an initiative. +Use this skill as the portable workflow layer for work that is too large, +risky, cross-cutting, or stateful to run from chat history alone. + +The default operations root is `./.ub-workflows/` unless the host deliberately +chooses another root. + +The normalized model is product-agile hybrid: + +```text +Product Vision -> Product Options -> Outcome Waves -> Initiatives -> Discoveries -> Sprints +``` + +The model combines: + +1. dual-track agile: discovery validates options before delivery pulls work; +2. goal-oriented roadmapping: product vision stays broad while waves and + initiatives carry current outcomes; +3. Scrum-like sprint execution: one sprint goal, inspect/adapt, and explicit + start approval when reviewed mode is active; +4. Kanban-style flow controls: explicit policies, WIP limits, pre-commitment + options, feedback loops, and stale-candidate revalidation; +5. Shape Up influence: lightweight bet framing, appetite, circuit breakers, + and no backlog sludge; +6. appetite-boxed forecast calibration: candidate counts are forecasts, and + expansion requires operator choice after scoped options and tradeoffs. + +## Canonical Layout + +```text +PROJECT_ROOT/ + AGENTS.md + SOURCE_ATLAS.md + .ub-workflows/ + AGENTS.md + vision.md + options.md + status.md + WORKFLOW_ATLAS.md + SOURCE_PACK_ATLAS.md + source-packs/ + .gitkeep + YYYY-MM-DD-slug/ + waves/ + .gitkeep + wNN-wave-slug/ + wave.md + discoveries/ + .gitkeep + wNN-dNN-slug.md + source-packs/ + .gitkeep + YYYY-MM-DD-slug/ + initiatives/ + .gitkeep + iNN-initiative-slug/ + initiative.md + options.md + roadmap.md + index.md + discoveries/ + .gitkeep + wNN-iNN-dNN-slug.md + sprints/ + .gitkeep + wNN-iNN-sNN-sprint-slug/ + sprint.md + decision-log.md + closeout.md + evidence/ + .gitignore + index.md +``` + +Naming rules: + +1. wave IDs are project-sequenced: `w01`, `w02`, etc.; +2. initiative IDs reset per wave: `i01`, `i02`, etc.; +3. wave-level discoveries use `wNN-dNN-slug.md` and reset per wave; +4. initiative discoveries use `wNN-iNN-dNN-slug.md` and reset per initiative; +5. sprints use `wNN-iNN-sNN-sprint-slug/` and reset per initiative; +6. source packs use `YYYY-MM-DD-slug/` using creation, original research, + earliest known history, or migration date with a note. + +## Lanes + +Choose the lane that lets the accepted objective be completed, validated, and +recovered without unrelated expansion: + +1. direct bounded work: a small single-session change with no durable planning + surface needed; +2. wave/initiative workflow: multi-session, staged, risky, product-shaping, + or cross-cutting work that needs options boards, discovery, roadmaps, + sprints, closeouts, and resumable evidence. + +Promote lanes when the current lane no longer provides enough durable surface +to finish and prove the accepted objective. +Record the promotion reason in the artifact that now owns the work. ## Embedded Contract -These rules are the base contract of this skill and must not depend on a -secondary document to be applied correctly. - -1. Make the lane choice explicit before opening durable artifacts: direct - bounded work, lightweight spec, or initiative. -2. Keep direct bounded work narrow: do not stay direct once the conversation - becomes planning-heavy, medium-sized, execution-shaped, or useful enough - that another operator would benefit from a durable mini-contract. -3. Promote to a lightweight spec when brainstorming becomes real planning, - even before implementation starts, if the work now needs durable - assumptions, scope, options, validation, or an execution shape. -4. Promote to an initiative once the work clearly needs PRD-level - decomposition, sequencing, stop-resume safety, or staged delivery rather - than a bounded spec alone. -5. Surface a short promotion note when the lane changes so the user can see - why direct bounded work or a lightweight spec is no longer the smallest safe - surface. -6. For initiatives, make `prd.md` self-contained before generating - `roadmap.md`. -7. Treat `roadmap.md` as the durable post-plan artifact. -8. Do not prepare sprint content, initialize sprint folders, or begin sprint - execution until `roadmap_ready: pass`. -9. Prepare each sprint as a standalone `sprint.md` before the sprint begins. -10. Sprint execution never starts from placeholder-only sprint shells. -11. In `reviewed` mode, after sprint closeout, a request like `ok lets move on` - or `Start the next sprint.` opens the next sprint preview only. -12. In `reviewed` mode, that preview analyzes the next sprint, surfaces any - path-changing questions, and asks for one explicit start approval. -13. In `reviewed` mode, a later approval message starts execution and, when - used, records `sprint_start_ready: pass`; it does not trigger a second start - prompt. -14. End every initiative with a final audit and a retained note, then stop for - human review before archive. - -## Initiative Lifecycle - -Drive initiative work through this ordered flow: - -1. intake classification -2. lane choice -3. research and discovery when durable planning is needed -4. execution-ready PRD -5. initiative scaffold and planning baseline -6. roadmap generation and approval -7. sprint-content preparation -8. sprint materialization and start readiness -9. ordered sprint execution -10. sprint closeout with explicit handoff and review pause -11. final audit and review pause -12. retained note and archive decision - -## Initiative-Level Gates - -Use these lifecycle gates for initiatives: - -1. `research_ready` -2. `prd_ready` -3. `roadmap_ready` -4. `sprint_content_ready` -5. `sprint_start_ready` -6. `sprint_closeout` -7. `archive_ready` -8. `initiative_complete` - -Allowed states: - -1. `pass` -2. `fail` -3. `blocked` - -These are workflow gates, not repository governance gates. +1. Keep reusable workflow rules in this skill, not in one repository overlay. +2. Keep repository overlays thin: project facts, current pointers, local + validation commands, domain boundaries, and repository-specific constraints. +3. `vision.md` owns the adaptable product north star. +4. Root `options.md` owns curated product-level, future-wave, and + unknown-owner options before commitment. It is not a backlog ledger, + completion history, or execution authorization surface. +5. `status.md` owns current product posture, wave sequencing, active pointers, + blockers, WIP state, candidate tracks, retained-context routes, and next + allowed action. +6. `SOURCE_ATLAS.md` owns project-root source routing. Bootstrap seeds it with + a one-time scan; later updates are event-based when source boundaries move. +7. Root `AGENTS.md` owns the local agent overlay. Bootstrap creates or patches + only a small managed workflow-routing section. +8. A workflow-root guide, split product/live-state startup files, and a root + specs lane are not canonical workflow surfaces. +9. Outcome waves are adaptive product slices; they may split, merge, grow, or + shrink through reviewed discovery. +10. Initiatives are thematic wave-local bets; they may pause and resume. +11. Initiative-local `options.md` owns possible insertions before that + initiative closes. Product-level or later-wave options move to root + `options.md`. +12. Discoveries are normal upstream steering work, not exceptional ceremony. +13. Discoveries and sprint previews record user or operator evidence status as + `used`, `not triggered`, or `deferred` so technical work still states + whether real-user or operator feedback shaped the decision. +14. Sprints are delivery slices pulled from accepted discovery or a reviewed + sprint preview. +15. Default WIP is constrained dual-track: one active delivery sprint and one + active discovery per active initiative; wave discovery is active only for + activation, transition, or reroute. +16. Future work may live in root or initiative-local options boards before + commitment. Options are ordered by document order within horizon lanes, but + are not delivery commitments, status ledgers, or execution queues. +17. Remove an option after it is promoted, rejected, merged, or completed and + the receiving artifact owns the durable trace. Do not maintain a `Done` + lane in options boards. +18. Before activating a new wave or initiative, review root options and + unresolved local options from the closing initiative. +19. Before closing an initiative, promote, move, reject, or remove every local + option. Do not archive completed cards in the options board itself. +20. Run options validation at wave or initiative transition, option promotion, + initiative closeout, terminal audit, and when a sprint preview is pulled + from an option. +21. Reusable workflow-system changes that affect artifact ownership, + lifecycle gates, scaffold output, transition policy, or recovery context + require a compact workflow-improvement discovery or equivalent accepted + decision record. +22. Revalidate candidates on touch: any candidate not prepared from current + evidence must pass fresh discovery or preview before execution. Use + discovery when route-changing uncertainty exists; use reviewed preview + only when a registered candidate is being freshly revalidated for start. +23. Discovery Triage is a fail-closed Routing Preflight, not a preview + appendix. Before choosing a reviewed preview, record trigger categories and + one outcome: `preview_ok`, `discovery_required`, + `operator_decision_needed`, or `not_triggered`. Trigger categories include + autonomy, authority, runtime-boundary, policy, evidence, + interoperability, agent-behavior changes, agent loops, harnesses, loop + continuation, goal judgment, budgets, and checkpoints. If triggered + evidence may change route, contract, scope, validation, runtime boundary, + or implementation path, record `discovery_required`; `preview_ok` is valid + only when the route is already decided and trigger evidence cannot change + those decisions. Use `not_triggered` only with a concrete reason. +24. Discovery-driven sequence changes must be promoted into the owning + `roadmap.md` before acceptance; closeout-driven next-route changes must be + promoted before sprint closeout. +25. Sprint previews identify repo-owned operational surfaces when triggered: + owner, lifecycle, visibility, safety policy, validation path, and + inventory/topology/registry/route-map impact. If uncertainty about those + facts may change scope, architecture, risk, or acceptance criteria, + promote discovery before execution. +26. Each wave and initiative records qualitative Outcome Signals for product + or user value, delivery flow, quality or stability, and context or evidence + cost. These are routing signals, not a metrics ledger. +27. Each initiative and sprint records lightweight bet framing: appetite, + success evidence, circuit breaker, non-goals, and deferral path. +28. Waves and initiatives use Appetite-Boxed forecasting by default: forecast + counts are not commitments, sequence expansion is not automatic + adaptation, and adding work requires the agent to present options, + tradeoffs, and a recommended path for explicit operator decision. +29. Wave and initiative charters record Forecast And Appetite; roadmaps record + Forecast Control; discoveries and reviewed previews record Forecast Impact + when they change sequence. +30. Sprint previews record Product Increment Contribution as `direct`, + `enabling`, or `audit`; enabling sprints must name the visible increment + they unblock and why a direct slice is not viable. +31. Two consecutive enabling or prerequisite sprints trigger a route review: + propose shipping a vertical proof, cutting/deferring scope, rerouting, or + explicitly buying more enabling work. +32. Major capability candidates decompose prerequisite risks and the first + usable product increment before acceptance. +33. In reviewed mode, a request to move on opens a preview only; execution + starts only after a later explicit approval. +34. New sprint packs include `decision-log.md`, `closeout.md`, and + `evidence/index.md`. +35. `evidence/index.md` is the T4 claim-to-proof router. It records validated + claims, evidence files, required objective gates, optional or + not-triggered gates, redaction posture, promotion targets, and read policy + without becoming a narrative closeout. +36. Generated runtime state under sprint evidence (any + project-specific scratch directory) is local scratch by default. + Commit only reviewed no-secret evidence files or an explicitly + approved export. +37. Sprint closeout includes a required outcome and learning review with four + prompts: what did this sprint achieve, how did it make the project better, + what could have been done better, and whether the learning changes the + next route, stays local, or suggests a workflow improvement. +38. Sprint closeout records Forecast Delta: planned versus actual, hidden + prerequisite discovered, remaining forecast impact, and whether roadmap, + index, or status were updated. +39. Material closeout claims must be backed by `evidence/index.md`. Required + objective proof cannot be deferred while closing the original objective as + passed; missing or failing required proof keeps the sprint active or + blocked until the operator explicitly changes scope or the proof passes. +40. Sprint closeout includes a focused mini-retro: process friction, evidence + cost, context cost, decision latency, workflow adjustment if needed, and a + retro evidence check covering objective signal, controllability, and + repeated friction. +41. Repeated or structural workflow friction is promoted into this skill; + one-off repo friction stays local. +42. Project evolution mode defaults to `forward-only` unless a host records a + reviewed compatibility-preserving decision. +43. When the active evolution mode requires forward migration, broad boundary + changes must include an impact inventory and must update, remove, or + explicitly defer each affected owned surface before closeout. +44. Source packs are retained context, not execution authorization, live state, + or backlog. +45. Trace tokens are owner-only lookup anchors. Use triggered T3 initiative + `index.md` trace routes before broad workflow search, and do not add trace + tokens to discoveries, sprint packs, closeouts, decision logs, or evidence + indexes. ## Interaction Modes -Interaction mode changes visibility, pause behavior, and interruption behavior. -It does not weaken readiness rules. - -1. `reviewed` - - default mode - - user-facing pre-sprint preview as a distinct checkpoint - - explicit human approval before execution - - user-facing post-execution reporting with considerations and watchouts - - the post-execution report is the pause boundary after a sprint - - a later move-on request opens the next pre-sprint preview and start - approval prompt -2. `flow` - - short pre-execution note - - richer post-execution reporting - - manual advancement after each sprint or bounded execution chunk -3. `auto` - - internal pre-execution analysis by default - - concise post-execution reporting - - automatic advancement unless interruption conditions are met -4. `continuous` - - user-facing alias: `yolo` - - internal analysis and artifact updates still required - - no routine pause between sprints or bounded execution chunks - - interrupt only when a major blocker or conflict requires user resolution - -Mode precedence: - -1. explicit user turn override -2. persisted artifact mode -3. default fallback = `reviewed` - -Persistence by lane: +1. `reviewed` is the default: preview before execution, explicit later start + approval, post-execution report, and pause after closeout. +2. `flow`: short pre-execution note, post-execution report, manual advancement. +3. `auto`: internal pre-execution analysis and automatic advancement unless a + blocker, conflict, or path-shaping decision requires interruption. +4. `continuous` / `yolo`: no routine pauses, but all gates, artifacts, and + interruption rules still apply. -1. initiative lane: persist in initiative artifacts -2. lightweight-spec lane: persist in `spec.md` -3. direct bounded lane: runtime only unless promoted into a durable artifact +Mode changes visibility and pause behavior. It does not weaken readiness, +evidence, or writeback requirements. -Question handling: +## Objective-Complete Rule -1. for multiple-choice user prompts, follow the shared choice-question - contract in `../ub-authoring/references/authoring-conventions.md` -2. in `reviewed` mode, keep the same decision structure as the canonical - reviewed-mode pre-sprint preview pattern -3. resolve the questions that change the sprint path before the single explicit - start-approval question +Choose an objective-complete action: implement and validate all work required +for the accepted sprint objective and exit criteria. Avoid unrelated expansion, +but do not cut, defer, or split required proof just to preserve scope or +budget. -For non-trivial `reviewed`-mode sprints, the preview should lead with: - -1. `What Repo Truth Says` -2. `Inference` -3. `Implementation Paths` -4. `Recommendation` - -Artifact or validation bookkeeping is secondary unless it is itself the repo -truth that materially shapes the sprint. +When a sprint, preview, or closeout uses words like `smallest`, `narrow`, or +`only as needed`, interpret them as the smallest objective-complete vertical +slice, not the smallest patch that makes the first focused test pass. Every +repo-owned affected surface named by the sprint scope, every required evidence +gate, and every exit criterion remains in scope unless the operator explicitly +changes the objective. ## Load References By Trigger -Use these load tiers literally. -If a trigger is not active, do not read the reference just because it exists. - -- `[phase:lifecycle-detail]` Read `references/workflow-contract.md` for the - detailed lifecycle, reviewed-mode preview pattern, and stop-resume rules. +- `[phase:lifecycle-detail]` Read `references/workflow-contract.md` for + detailed operating rules, WIP policy, reviewed-mode previews, and recovery. - `[phase:artifact-create|artifact-validate]` Read - `references/artifact-contracts.md` when creating or validating initiative or - lightweight-spec artifacts. + `references/artifact-contracts.md` when creating or validating workflow + artifacts. +- `[edge:context-management|frontmatter|context-budget]` Read + `references/context-management.md` when interpreting `context_tier`, + `summary_budget_lines`, phase read budgets, atlas routes, context receipts, + retained-context reads, or evidence/writeback receipt shapes. +- `[edge:trace-token|trace-lookup|workflow-search]` Read + `references/trace-tokens.md` when searching workflow history, interpreting + trace IDs or tags, adding trace metadata, or deciding where trace anchors + belong. - `[phase:gate-eval|closeout|readiness]` Read - `references/validation-and-completion.md` when evaluating readiness, gate - transitions, closeout, or completion. -- `[edge:helper-use]` Read `references/scaffold-helper.md` only when using or + `references/validation-and-completion.md` when evaluating readiness, + closeout, archive, or completion. +- `[edge:helper-use]` Read `references/scaffold-helper.md` before using or explaining the deterministic helper. +- `[edge:strict-placeholder-validation|options-validation]` Read + `references/placeholder-contract.md` when strict placeholder validation is + relevant. Read `references/validation-and-completion.md` when options-board + validation, transition checks, or closeout checks are relevant. - `[edge:governance-escalation]` Read `references/governance-bridge.md` only - when explicit governance alignment, evidence depth, or audit mapping is in - play. -- `[edge:strict-placeholder-validation]` Read - `references/placeholder-contract.md` only when strict placeholder validation - or the placeholder checker is relevant. -- `[edge:authoring-conventions]` Read `../ub-authoring/references/authoring-conventions.md` - only when adjusting shared routing or cross-skill authoring structure. - -Do not treat human help docs as operational dependencies. + when explicit governance mapping is active. +- `[edge:authoring-conventions]` Read + `../ub-authoring/references/authoring-conventions.md` when shared routing, + naming, or choice-question authoring is being changed. ## Bundled Assets -Use the assets under `assets/operations-root/`, -`assets/initiative-template/`, and `assets/lightweight-spec-template/` as the -canonical internal templates for this skill. - -Use `scripts/scaffold_initiative.py` when deterministic scaffold creation is -preferred over manual copying. - -Rules: - -1. Bootstrap `./.ub-workflows/` when it is missing instead of asking the user - to create it by hand. -2. Do not require a copied local `initiative-template/` inside the generated - operations root. -3. Do not edit the canonical asset templates for one specific initiative. -4. Replace placeholders explicitly; do not leave repository-specific facts - implied. -5. Do not set human-owned approval gates on behalf of the user. - -## When Not To Use - -- Do not use this skill for governance-only questions or deterministic gate - execution; defer those to `ub-governance`. -- Do not use this skill when the work is already a small direct code change - that does not need durable planning artifacts. -- Do not use this skill as a substitute for language or framework - implementation guidance once the execution surface is already clear. - -## Coordination With Sibling Skills - -- Load and apply `ub-quality` whenever creating or editing workflow documents. -- Workflow artifacts explicitly required by this skill are allowed outputs - under ub-quality's document-generation policy, but they still must satisfy - ub-quality formatting and structure rules. -- Load `ub-governance` only when the repository wants explicit governance - alignment, evidence depth, or audit mapping. -- Do not require ub-governance for basic scaffolding, PRD generation, or - ordinary lightweight-spec work. - -## Core Workflow - -1. Detect whether the user needs direct bounded work, lightweight-spec shaping, - initiative PRD shaping, roadmap generation, sprint preparation, sprint - initialization, sprint execution support, or final audit. -2. Inspect repository truth before writing repository-specific validation or - adaptation details. -3. Make the scale decision explicit and promote out of direct bounded work as - soon as the conversation needs a durable planning surface. -4. If `./.ub-workflows/` does not exist, bootstrap it through - `scripts/scaffold_initiative.py`. -5. Create or refine a lightweight spec when the work is still bounded but now - needs assumptions, scope, options, validation, or an execution plan written - down. -6. Bias medium planning work toward a lightweight spec first, but scaffold a - new initiative as soon as the work clearly needs a PRD, roadmap, or staged - execution model. -7. Copy a source PRD into `./prd.md` without rewriting it. -8. Generate the full roadmap in one pass before sprint execution starts. -9. Surface a review checklist before `roadmap_ready: pass` can be set. -10. Prepare each planned sprint as a standalone execution-ready `sprint.md`. -11. Initialize sprint folders only after roadmap approval and in a way that - preserves prepared sprint content. -12. Execute only the active sprint according to the active interaction mode, - updating `roadmap.md`, `README.md`, `rollup.md`, `decision-log.md`, and - `closeout.md` as state changes. -13. Treat validation, documentation synchronization, and completion evidence - as gating conditions for both sprint closeout and initiative completion. -14. Archive only when the user explicitly asks for it and the completion - controls pass. - -## Repository Defaults - -1. Treat `./.ub-workflows/specs/` as the default home for lightweight specs. -2. Treat `roadmap.md` as the smallest live progress document for an - initiative. -3. Keep roadmap sprint entries rich enough to prevent omissions: path, goal, - dependencies, validation focus, subtasks, and evidence folder. -4. Treat sprint preparation as a distinct lifecycle phase; do not treat - initialized directories or placeholder sprint shells as execution-ready. -5. Treat sprint `decision-log.md` as the default sprint-memory surface and - `rollup.md` as the initiative-level carry-forward surface. -6. Keep `research/` and `exceptions/` visibly secondary to the main workflow - artifacts. -7. Treat roadmap approval and archive readiness as human-owned checkpoints. -8. Default new initiatives and lightweight specs to interaction mode - `reviewed` until the user explicitly changes it. -9. In user-facing execution notes, include a concise mode reference so the - user can see the available modes without opening extra docs. -10. Surface lane choice routinely only when promotion happens or when the user - explicitly asks, so very small direct work stays lightweight. -11. Bias planning-heavy bounded work toward lightweight specs, and bias - clearly multi-phase or cross-cutting work toward initiatives earlier than a - purely minimal reading would. +Use `assets/operations-root/` and `assets/initiative-template/` as canonical +templates. Use `scripts/scaffold_workflow.py` for deterministic bootstrap, +wave, initiative, discovery, source-pack, sprint, and archive operations. Use +`scripts/check_workflow_options.py` for options-board transition, closeout, +terminal-audit, and stale-card validation. ## Output Requirements -When using this skill for non-trivial workflow work, include: - -1. `phase_note` -2. `mode_note` -3. `scope_note` -4. `decision_note` -5. `promotion_note` when lane escalation happens -6. `artifact_note` -7. `gate_note` -8. `validation_note` -9. `next_action_note` - -## Completion Checklist +For non-trivial workflow work, report: -- The lane choice is explicit. -- Lane promotion is explicit when work moves from direct bounded work to a - lightweight spec or from a lightweight spec to an initiative. -- The lifecycle phase is explicit. -- The current initiative-level gate is explicit. -- Discovery and PRD readiness are explicit before roadmap generation. -- The PRD is self-contained before roadmap generation. -- The roadmap is the durable approved planning artifact before sprint - initialization begins. -- `roadmap_ready: pass` is set only after explicit human approval. -- Sprint content is prepared before sprint execution begins. -- Sprint execution never starts without an explicit user request. -- Sprint execution never starts from a placeholder-only sprint shell. -- `reviewed` and `flow` pause after sprint execution; `auto` and - `continuous` only continue when their interruption rules allow it. -- The workflow still stops after final audit for human review before archive. -- Each sprint document is standalone and resumable. -- Archive readiness is surfaced explicitly before any archive action. -- Touched workflow documents satisfy ub-quality formatting and structure rules. -- The retained note captures durable outcomes after completion. +1. lane and scale decision; +2. active artifact owner; +3. WIP and gate state; +4. chosen path and rejected alternative when path choice matters; +5. validation and evidence expectation; +6. next allowed action. diff --git a/.agents/skills/ub-workflow/assets/initiative-template/AGENTS.md b/.agents/skills/ub-workflow/assets/initiative-template/AGENTS.md deleted file mode 100644 index 8adb9b0..0000000 --- a/.agents/skills/ub-workflow/assets/initiative-template/AGENTS.md +++ /dev/null @@ -1,45 +0,0 @@ -# Initiative Root — AGENTS.md - -## Scope - -Applies to this initiative root and its descendants. - -## Local Rules - -- `roadmap.md` is the smallest live progress document for the initiative. -- `rollup.md` is the readable cross-sprint summary, not a replacement for - sprint-local truth. -- Read `roadmap.md` first when resuming work. -- Treat each sprint's `sprint.md` as a standalone sprint PRD. -- Treat each sprint's `decision-log.md` as the running sprint-level memory - surface. -- Do not assume the master `prd.md` must be open to execute a sprint. -- Treat `roadmap.md` as the durable planning artifact after PRD work is done. -- Keep sprint execution sequential unless the roadmap explicitly says otherwise. -- End the roadmap with a mandatory final audit step. -- Keep `research/` supportive and bounded; do not use it as a general sprint - note store. -- Keep `exceptions/` for explicit exception records only. - -## Resume Order - -1. `./roadmap.md` -2. `./rollup.md` -3. the latest sprint `closeout.md` -4. the active or next sprint `sprint.md` -5. the active sprint `decision-log.md` when it materially affects execution -6. `./README.md` -7. `./prd.md` only if needed for additional initiative-level context - -## Update Discipline - -- Update `roadmap.md` after every meaningful sprint state change. -- Update `rollup.md` when a sprint materially changes cross-sprint direction, - assumptions, or validation posture. -- Update `README.md` when blockers, phase, or next step changes. -- Keep the active sprint's `decision-log.md` current during execution. -- Keep the active sprint's `closeout.md` current before stopping work. -- Do not create sprint folders until `roadmap_ready: pass`. -- Create sprint folders from the canonical `ub-workflow` sprint template only - when initializing the approved roadmap. -- Record the user's follow-up audit or refactor decision before closing the initiative. diff --git a/.agents/skills/ub-workflow/assets/initiative-template/README.md b/.agents/skills/ub-workflow/assets/initiative-template/README.md deleted file mode 100644 index ca4e066..0000000 --- a/.agents/skills/ub-workflow/assets/initiative-template/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# Initiative Status - -## Snapshot - -| Field | Value | -| --------------------- | -------------------------- | -| Initiative | REPLACE_INITIATIVE_NAME | -| Owner | REPLACE_OWNER | -| Imported on | REPLACE_IMPORTED_ON | -| Interaction mode | `reviewed` | -| Governance bridge | REPLACE_GOVERNANCE_BRIDGE | -| Governance profile | REPLACE_GOVERNANCE_PROFILE | -| Current phase | REPLACE_PHASE | -| Current gate | REPLACE_GATE_STATE | -| Roadmap status | REPLACE_ROADMAP_STATUS | -| Active sprint | REPLACE_CURRENT_SPRINT | -| Last completed sprint | REPLACE_LAST_COMPLETED | -| Next step | REPLACE_NEXT_ACTION | -| Blockers | REPLACE_BLOCKERS | - -## Resume Here - -1. Read `./roadmap.md`. -2. Read `./rollup.md` for the readable cross-sprint summary when it exists. -3. Read the latest sprint `closeout.md` if execution has already started. -4. Read the active or next sprint `sprint.md`. -5. Read the active sprint `decision-log.md` when you need the running sprint - decision history. -6. Read `./README.md` if you need the root summary. -7. Review or generate `./roadmap.md` first, then initialize sprint artifacts - only after `roadmap_ready: pass`. - -## Validation Pointers - -- Validation baseline: REPLACE_VALIDATION_BASELINE -- Documentation sync status: REPLACE_DOCUMENTATION_STATUS -- Exception records: REPLACE_EXCEPTION_POINTERS diff --git a/.agents/skills/ub-workflow/assets/initiative-template/exceptions/.gitkeep b/.agents/skills/ub-workflow/assets/initiative-template/exceptions/.gitkeep deleted file mode 100644 index 2fa992c..0000000 --- a/.agents/skills/ub-workflow/assets/initiative-template/exceptions/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -keep diff --git a/.agents/skills/ub-workflow/assets/initiative-template/exceptions/AGENTS.md b/.agents/skills/ub-workflow/assets/initiative-template/exceptions/AGENTS.md deleted file mode 100644 index 0f94147..0000000 --- a/.agents/skills/ub-workflow/assets/initiative-template/exceptions/AGENTS.md +++ /dev/null @@ -1,12 +0,0 @@ -# Exceptions — AGENTS.md - -## Scope - -Applies to the `exceptions/` directory inside one initiative root. - -## Local Rules - -- Record only explicit, bounded exceptions here. -- Every exception note should name the owner, expiration condition, and the - affected workflow gate. -- Remove stale exception records during sprint closeout or final audit. diff --git a/.agents/skills/ub-workflow/assets/initiative-template/exceptions/exception-template.yaml b/.agents/skills/ub-workflow/assets/initiative-template/exceptions/exception-template.yaml deleted file mode 100644 index 483a8b5..0000000 --- a/.agents/skills/ub-workflow/assets/initiative-template/exceptions/exception-template.yaml +++ /dev/null @@ -1,9 +0,0 @@ -# Copy this file to a dated name such as YYYY-MM-DD-governance-exception.yaml -# when a governed initiative needs a bounded exception record. - -governance_exception: - owner: "@team-or-person" - rationale: "Why the baseline policy cannot be applied right now" - created_at: "YYYY-MM-DD" - expires_at: "YYYY-MM-DD" - follow_up: "https://tracker.example.com/ISSUE-123" diff --git a/.agents/skills/ub-workflow/assets/initiative-template/index.md b/.agents/skills/ub-workflow/assets/initiative-template/index.md new file mode 100644 index 0000000..d892ac4 --- /dev/null +++ b/.agents/skills/ub-workflow/assets/initiative-template/index.md @@ -0,0 +1,43 @@ +# Initiative Index + +This is the triggered T3 compact lookup and durable-history surface for the +initiative. It is not the active plan and must not duplicate sprint closeouts. + +## Current Snapshot + +- State: `not started` +- Active route: `roadmap.md` +- Retained note: `retained-note.md` after final audit. + +## Forecast Snapshot + +- Appetite state: `within_appetite` +- Bought or deferred tranche: none. +- Current forecast note: use `roadmap.md` for active Forecast Control. + +## Durable Direction + +No durable direction has been proved yet. + +## Artifact Routes + +| ID | Type | Status | Path | Read Trigger | +| --- | --- | --- | --- | --- | +| options | options board | active | `options.md` | initiative-local insertion or closeout check | +| pending | discovery | pending | `discoveries/` | first accepted discovery | +| pending | sprint | pending | `sprints/` | first sprint closeout | + +## Trace Routes + +| Trace ID | Kind | Status | Tags | Owner | Evidence | Read Trigger | +| --- | --- | --- | --- | --- | --- | --- | +| pending | discovery | pending | n/a | `discoveries/` | n/a | first accepted discovery | + +## Update Rules + +- Add one compact line for each accepted discovery, completed sprint, evidence + index, trace route, supersession, and durable decision. +- Promote sequence changes into `roadmap.md`; do not leave them only in a + discovery or closeout. +- Keep full details in discoveries, sprint decision logs, closeouts, and + evidence indexes. diff --git a/.agents/skills/ub-workflow/assets/initiative-template/initiative.md b/.agents/skills/ub-workflow/assets/initiative-template/initiative.md new file mode 100644 index 0000000..9ad77ff --- /dev/null +++ b/.agents/skills/ub-workflow/assets/initiative-template/initiative.md @@ -0,0 +1,55 @@ +# Initiative: REPLACE_INITIATIVE_TITLE + +## Summary + +Replace with the initiative summary. + +## Outcome Bet + +- Appetite: REPLACE_APPETITE +- Success evidence: REPLACE_SUCCESS_EVIDENCE +- Circuit breaker: REPLACE_CIRCUIT_BREAKER +- Deferral path: REPLACE_DEFERRAL_PATH + +## Outcome Signals + +- Product/user signal: Replace with product, user, customer, or operator value signal. +- Delivery/flow signal: Replace with delivery, WIP, blocked-time, or route-clarity signal. +- Quality/stability signal: Replace with correctness, reliability, validation, or failure-handling signal. +- Context/evidence cost signal: Replace with context, evidence, or recovery-cost signal. + +## Forecast And Appetite + +- Appetite: REPLACE_APPETITE +- Forecast range/count: Replace with candidate count, timebox, or tranche. +- Confidence: Replace with high, medium, or low and why. +- Throughput basis: Replace with recent completed sprint evidence or `not available`. +- Known unknowns: Replace with the main forecast risks. +- Scope hammers: Replace with operator-choice cut, defer, or reframe options. +- Expansion trigger: Replace with what requires operator decision or buy-more. + +## Goals + +1. Replace with the first goal. + +## Non-Goals + +1. Replace with the first non-goal. + +## Constraints + +1. Project evolution mode follows the host repository policy; record the active + mode before broad boundary changes. + +## Current Status + +- Interaction mode: `reviewed` +- Active discovery: `none` +- Active sprint: `none` +- Current gate: `initiative_created` +- Next allowed action: shape or accept initiative discovery before delivery. + +## Durable Decisions + +Record initiative-level decisions here, or point to the discovery, sprint +closeout, initiative index, or retained note that owns the detail. diff --git a/.agents/skills/ub-workflow/assets/initiative-template/options.md b/.agents/skills/ub-workflow/assets/initiative-template/options.md new file mode 100644 index 0000000..683abba --- /dev/null +++ b/.agents/skills/ub-workflow/assets/initiative-template/options.md @@ -0,0 +1,30 @@ +# Initiative Options Board + +This board preserves possible initiative-local insertions before closeout. It +is not a sprint queue, completion ledger, or execution authorization surface. + +Order is document order within each lane. Order means current review +preference, not delivery commitment. + +## Board Rules + +- Keep only options that may still affect this initiative before closeout. +- Move product-level or later-wave options to root `options.md`. +- Remove a card after it is promoted, rejected, merged, or completed and the + receiving artifact records the durable trace. +- Before initiative closeout, promote, move, reject, or remove every local + option. + +## Possible Initiative Insertion + +No active cards. + +## Deferred To Product Options + +No active cards. + +## Update Rules + +Do not keep completed or rejected cards here as a history lane. Durable traces +belong in discoveries, roadmap decisions, sprint closeouts, evidence indexes, +source packs, and git history. diff --git a/.agents/skills/ub-workflow/assets/initiative-template/prd.md b/.agents/skills/ub-workflow/assets/initiative-template/prd.md deleted file mode 100644 index 0db7c66..0000000 --- a/.agents/skills/ub-workflow/assets/initiative-template/prd.md +++ /dev/null @@ -1,90 +0,0 @@ -# Product Requirements Document - -## Summary - -Replace with a concise summary of the initiative. - -## Background Or Problem Statement - -Replace with the current problem, opportunity, or research question. - -## Goals - -1. Replace with the primary goal. -2. Replace with the secondary goal. - -## Non-Goals - -1. Replace with a clear non-goal. -2. Replace with another clear non-goal. - -## Scope - -Replace with the exact initiative scope. - -## Principles - -1. Replace with the guiding product or engineering principle. -2. Replace with the quality or delivery principle. - -## Current-State Diagnosis - -Replace with repository truth, research findings, or observed constraints. - -## Option Analysis - -### Chosen Path - -Replace with the selected approach and why it best fits the initiative. - -### Rejected Alternative - -Replace with one rejected alternative and concise pros and cons. - -## Success Criteria - -1. Replace with a verifiable outcome. -2. Replace with another verifiable outcome. - -## Validation Expectations - -1. Replace with the concrete validation command, check, or acceptance method - for the initiative. -2. Replace with any required test-signal, regression, build, or audit checks - when behavior changes are in scope. - -## Documentation Touch Points - -1. Replace with the docs, architecture notes, or synchronized artifacts that - must be updated or explicitly confirmed unchanged. -2. Replace with how documentation synchronization will be validated. - -## Governance Bridge - -Replace with `Level 0`, `Level 1`, or `Level 2` and the rationale. - -If `Level 2` applies, also record the governance profile as `lean` or -`advanced`. - -## Dependencies And Constraints - -1. Replace with a dependency. -2. Replace with a constraint. - -## Execution Risks - -1. Replace with a primary delivery or technical risk. -2. Replace with the mitigation or fallback. - -## Readiness Checklist - -- [ ] problem is clearly defined -- [ ] goals and non-goals are explicit -- [ ] chosen path is justified -- [ ] one alternative was evaluated and rejected -- [ ] success criteria are verifiable -- [ ] validation expectations name concrete commands or checks where known -- [ ] documentation touch points are explicit -- [ ] governance bridge level is explicit when governance coordination is needed -- [ ] dependencies and risks are explicit -- [ ] another operator could execute without chat history diff --git a/.agents/skills/ub-workflow/assets/initiative-template/research/.gitkeep b/.agents/skills/ub-workflow/assets/initiative-template/research/.gitkeep deleted file mode 100644 index 2fa992c..0000000 --- a/.agents/skills/ub-workflow/assets/initiative-template/research/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -keep diff --git a/.agents/skills/ub-workflow/assets/initiative-template/research/AGENTS.md b/.agents/skills/ub-workflow/assets/initiative-template/research/AGENTS.md deleted file mode 100644 index 21f92cb..0000000 --- a/.agents/skills/ub-workflow/assets/initiative-template/research/AGENTS.md +++ /dev/null @@ -1,13 +0,0 @@ -# Research — AGENTS.md - -## Scope - -Applies to the `research/` directory inside one initiative root. - -## Local Rules - -- Keep research notes supportive, not authoritative. -- Preserve links back to `./prd.md` and `./roadmap.md` when a research note - materially influenced the approved plan. -- Do not treat research notes as a substitute for making `prd.md` or - `roadmap.md` self-contained. diff --git a/.agents/skills/ub-workflow/assets/initiative-template/retained-note.md b/.agents/skills/ub-workflow/assets/initiative-template/retained-note.md index 98b36bc..e6fcff7 100644 --- a/.agents/skills/ub-workflow/assets/initiative-template/retained-note.md +++ b/.agents/skills/ub-workflow/assets/initiative-template/retained-note.md @@ -1,39 +1,15 @@ # Retained Note -Status: not started +Write this after final audit. ## Outcome -Record the final initiative outcome during the final audit. +Replace with the final initiative outcome. -## What Shipped +## Evidence -Record the shipped capabilities only after execution is complete. +Replace with final evidence pointers. -## Preserve These Decisions +## Follow-Up -Record durable decisions that future work should preserve. - -## Useful Future Notes - -Record future operator context worth preserving. - -## Deferred Items - -Record intentionally deferred work and the follow-up condition or owner. - -## Governance Bridge Summary - -Record the governance bridge level used for this initiative. - -If governance coordination was active, also record the profile, exception -references, and ADR references that shaped the final decision. - -## Follow-Up Decisions - -Record requested or declined follow-up audits or refactors. - -## Validation Baseline - -Record the final validation commands, outcomes, evidence pointers, and -documentation-synchronization confirmation here during final audit. +Replace with accepted follow-up, parked work, or `none`. diff --git a/.agents/skills/ub-workflow/assets/initiative-template/roadmap.md b/.agents/skills/ub-workflow/assets/initiative-template/roadmap.md index 6f3550a..120f147 100644 --- a/.agents/skills/ub-workflow/assets/initiative-template/roadmap.md +++ b/.agents/skills/ub-workflow/assets/initiative-template/roadmap.md @@ -1,124 +1,54 @@ -# Sprint Roadmap +# Initiative Roadmap -Status: REPLACE_CURRENT_STATUS - -This is the small live progress document for the initiative. - -Generate the full ordered sprint roadmap from `./prd.md` before starting sprint -execution, review it until `roadmap_ready: pass`, then keep this file current -as the initiative moves forward. - -## Overall Checklist - -- [ ] Master PRD imported into `./prd.md` -- [ ] Master roadmap generated from `./prd.md` -- [ ] Roadmap reviewed and approved with `roadmap_ready: pass` -- [ ] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template -- [ ] Sprint execution started -- [ ] All sprint closeouts completed -- [ ] Final audit completed as the last roadmap item -- [ ] Follow-up audit or refactor decision recorded -- [ ] `./retained-note.md` written - -## Current Position - -- Interaction mode: `reviewed` -- Current sprint: `none` -- Last completed sprint: `none` -- Next sprint: REPLACE_NEXT_SPRINT -- Resume from: REPLACE_RESUME_FROM -- Active blockers: `none` - -## Roadmap Objective +## Objective Replace with the initiative objective. -## PRD Scope Summary - -In scope: - -1. Replace with the first in-scope area. -2. Replace with the second in-scope area. - -Out of scope: - -1. Replace with the first out-of-scope area. -2. Replace with the second out-of-scope area. - -## Sprint Sequence - -The number of implementation sprints is PRD-driven. - -Repeat the implementation sprint entry shape below for Sprint 01 through Sprint NN-1 as needed, then keep the final audit as the last roadmap item. - -Do not run `prepare-sprints` or `init-sprints` until this roadmap is complete, -reviewed, and the initiative `README.md` records `roadmap_ready: pass`. - -- [ ] Sprint 01 - Replace with sprint title - - Path: `./sprints/01-replace-me/sprint.md` - - Goal: Replace with sprint goal - - Depends on: `none` - - Validation focus: Replace with validation focus - - Subtasks: - - [ ] Replace with subtask - - [ ] Replace with subtask - - Evidence folder: `./sprints/01-replace-me/evidence/` - -- [ ] Sprint 02 through Sprint NN-1 - Repeat this entry shape as many times as the PRD requires - - Path: `./sprints/NN-replace-me/sprint.md` - - Goal: Replace with sprint goal - - Depends on: `Sprint NN-1 - Replace with prior sprint title` or `none` when parallel work is explicitly allowed - - Validation focus: Replace with validation focus - - Subtasks: - - [ ] Replace with subtask - - [ ] Replace with subtask - - Evidence folder: `./sprints/NN-replace-me/evidence/` +## Current Position -- [ ] Final Audit - Replace with audit title - - Path: `./sprints/NN-final-audit/sprint.md` - - Goal: verify full implementation completeness, synchronization, and follow-up needs - - Depends on: `all prior implementation sprints` - - Validation focus: completeness review, documentation synchronization, final quality gates, and follow-up audit/refactor review - - Subtasks: - - [ ] Confirm no material roadmap scope was missed - - [ ] Confirm documentation and synchronized artifacts are current where applicable - - [ ] Ask whether follow-up audits or refactors are wanted and record the answer - - Evidence folder: `./sprints/NN-final-audit/evidence/` +- Current state: `not started` +- Active or next sprint: `none` +- Active discovery: `none` +- WIP state: one discovery allowed, no active delivery sprint. -## Dependency Chain +## Forecast Control -1. Replace with the dependency chain between Sprint 01 and Sprint NN. +- Appetite state: `within_appetite` +- Completed count: 0 +- Registered remaining: 0 +- Forecast delta: none. +- Confidence: low until first discovery. +- Next scope tradeoff: none yet. +- Operator buy-more state: not needed. -## Validation Focus Per Sprint +## Active Or Next Sprint Route -1. Sprint 01: Replace with the sprint validation focus. -2. Sprint 02 through Sprint NN-1: Replace with the sprint validation focus for each planned implementation sprint. -3. Final Audit: completeness review, synchronized artifacts, final validation gates, and follow-up review. +No sprint is prepared yet. Delivery must pull from accepted discovery or a +reviewed sprint preview. -## Final Audit Step +## Adaptive Plan -The final audit must confirm at minimum: +1. Replace with the first probable candidate. +2. Pre-audit continuation window (`adaptive insertion`). +3. Final audit (`terminal audit`). -1. roadmap scope was actually executed -2. no material work was silently skipped -3. synchronized docs, tests, and related artifacts are current where applicable -4. required validation has been run or explicitly deferred -5. the user was asked about follow-up audits or refactors -6. the retained note reflects the final state +## Sequence Changes -## Handoff Expectations +No insertions, splits, reroutes, or deferrals yet. -1. Resume from `./roadmap.md` first, then open the active or next sprint's `sprint.md`, then the latest `closeout.md` once execution has begun. -2. Keep each sprint `sprint.md` standalone so execution does not depend on chat history or reopening the master `prd.md`. -3. Save deterministic evidence under the active sprint's `./evidence/` folder before changing sprint state. -4. Update this roadmap and `./README.md` after every meaningful sprint status change. +## Revalidation Rules -## Initiative Completion Condition +- Revalidate stale candidates on touch. +- Promote discovery-driven sequence changes into this roadmap before accepting + the discovery. +- Promote closeout-driven next-route changes into this roadmap before closing + the sprint. +- Keep product-level future-wave options in root `options.md`; keep + initiative-local possible insertions in local `options.md` until promoted, + moved, rejected, or removed. -The initiative is complete only when: +## Update Rules -1. all roadmap items have closeout records -2. the final audit sprint ends with a passing completion decision -3. required validation scenarios are covered and traceable -4. the canonical docs and synchronized artifacts are current -5. `./retained-note.md` has been written with the final follow-up decision +Update this roadmap only when objective, current position, active route, +candidate order, insertion points, WIP state, revalidation rules, or final +audit posture changes. Keep token history in `index.md`, not here. diff --git a/.agents/skills/ub-workflow/assets/initiative-template/rollup.md b/.agents/skills/ub-workflow/assets/initiative-template/rollup.md deleted file mode 100644 index e4cffb2..0000000 --- a/.agents/skills/ub-workflow/assets/initiative-template/rollup.md +++ /dev/null @@ -1,52 +0,0 @@ -# Initiative Rollup - -Status: not started - -## Purpose - -Use this file as the readable cross-sprint summary for the initiative. - -Keep raw sprint proof in each sprint's `./evidence/` folder, keep sprint -execution intent in each `./sprint.md`, keep running sprint decisions in each -`./decision-log.md`, and use this file to summarize the parts a future reader -should not have to reconstruct by opening every sprint directory in order. - -## Current Snapshot - -- Read `./README.md` for the live phase, gate, and next-step state. -- Read `./roadmap.md` for the ordered sprint checklist and dependency chain. -- Update this file whenever a sprint materially changes later-sprint - assumptions, direction, or validation posture. - -## Major Decisions - -- Record the cross-sprint decisions that later work should preserve. -- Summarize why the decision mattered and point to the owning sprint artifact - when that adds useful detail. - -## Sprint Highlights - -- Summarize each active or completed sprint in a few lines. -- Point to the relevant sprint `decision-log.md`, `closeout.md`, and - `evidence/` folder when a later reader needs deeper traceability. - -## Cross-Sprint Risks And Deferrals - -- Record risks, deferrals, or follow-up conditions that span more than one - sprint. -- Keep sprint-local issues in the owning sprint unless they materially affect - later work. - -## Validation And Evidence Rollup - -- Summarize the major initiative-level validation signals and where they live. -- Point to the owning sprint `evidence/` folders instead of copying raw logs - into this file. - -## Research And Exceptions Pointers - -- Use `./research/` only for supportive discovery worth retaining across - sprints. -- Use `./exceptions/` only for explicit bounded exception records. -- Keep routine sprint reasoning out of those folders; put it in sprint - `decision-log.md` files and this `rollup.md` instead. diff --git a/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/closeout.md b/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/closeout.md index 82e76af..6f2fc62 100644 --- a/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/closeout.md +++ b/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/closeout.md @@ -1,92 +1,55 @@ -# Sprint Closeout - -## environment_note - -Replace with the runtime and environment context for this sprint. - -## scope_note - -Replace with what this sprint evaluated, what stayed out of scope, and the -governance bridge level or profile when governance coordination was active. - -## decision_note - -Replace with the chosen path and one rejected alternative with concise pros and cons. - -## gate_note - -Replace with the initiative workflow gate state as -`sprint_closeout: pass|fail|blocked` and why. +--- +artifact_id : REPLACE_CLOSEOUT_ARTIFACT_ID +artifact_type : sprint_closeout +status : draft +context_tier : T3 +updated_at : REPLACE_UPDATED_AT +summary_budget_lines : 220 +--- -When governance is active, also record the governance gate type and result as -`merge|confidence|release: pass|fail|blocked`. - -## exception_note - -Replace with active exceptions or `none`. - -When governance is active, reference exception records that use the canonical -governance exception metadata. - -## validation_note - -Replace with the validation commands or checks and their outcomes. - -Also record any documentation or synchronized-artifact validation that was required for this sprint. - -When tests changed, record whether TG001-TG005 checks were run and what they -reported. +# Sprint Closeout -When governance is active, record governance-level validation commands, profile, -ADR references, and evidence paths that informed the gate decision. +## Outcome Summary -## done_verification_note +Replace with the sprint result. -Confirm whether the sprint definition of done is fully satisfied. +## Outcome And Learning Review -Minimum questions to answer: +- Achieved: Replace with what this sprint achieved. +- Project improvement: Replace with how the project is better after this sprint. +- Could be better: Replace with what could have been done better. +- Follow-up disposition: Replace with next-route change, local follow-up, workflow-improvement candidate, or `none`. -1. Is the planned functionality implemented? -2. Are there any known in-scope errors still open? -3. Are the required project quality gates green, including TG001-TG005 checks - when tests changed? -4. Are the relevant docs and synchronized artifacts updated or explicitly unchanged? -5. Is the validation evidence recorded? -6. Is `decision-log.md` current, and was `rollup.md` updated or explicitly left unchanged when warranted? +## Forecast Delta -## handoff_note +- Planned vs actual: Replace with forecasted scope versus actual result. +- Hidden prerequisite discovered: Replace with prerequisite, or `none`. +- Remaining forecast impact: Replace with effect on remaining candidates. +- Owner updates: Replace with `roadmap.md`, `index.md`, `status.md`, or `none`. -1. Replace with what finished. -2. Replace with what remains open. -3. Replace with the next recommended action. -4. Replace with what the next sprint should read first. +## Evidence -## follow_up_note +Replace with `evidence/index.md` or focused evidence files. -Record any requested or declined follow-up work. +## Validation -For the final audit sprint, answer at minimum: +Replace with commands, outcomes, and gate dispositions. Do not close as +passed when required objective proof is missing, failing, stale, or only +covered by a non-objective smoke path. -1. Was the user asked whether they want follow-up audits or refactors? -2. Which follow-up items were requested, if any? -3. Which follow-up items were explicitly declined, if any? -4. Did the final validation and documentation synchronization checks pass? -5. Are any governance exceptions, ADR waivers, or follow-up validation items - still open? +## Broader Writebacks -## post_execution_summary_note +Record which broader artifacts changed and why, or `none`. -Replace with the user-facing post-execution summary that should be recoverable -from this closeout. +## Mini-Retro -When the active mode surfaces post-execution reporting, include at minimum: +- Process friction: Replace with friction or `none`. +- Evidence cost: Replace with cost or `normal`. +- Context cost: Replace with cost or `normal`. +- Decision latency: Replace with approval, review, or blocked-time cost, or `normal`. +- Workflow adjustment: Replace with local adjustment, promotion candidate, or `none`. +- Retro evidence check: Replace with objective signal, controllability, and whether this repeated from prior work. -1. what changed -2. why it mattered -3. assumptions made -4. considerations moving forward -5. things to watch before the next sprint begins +## Handoff -In `reviewed` mode, this post-execution report is the pause boundary. A later -move-on request opens the next sprint's pre-sprint analysis and start-approval -prompt. +Replace with the next allowed action. diff --git a/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/decision-log.md b/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/decision-log.md index 6c3ce31..494fec6 100644 --- a/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/decision-log.md +++ b/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/decision-log.md @@ -1,33 +1,30 @@ -# Sprint Decision Log +--- +artifact_id : REPLACE_DECISION_LOG_ARTIFACT_ID +artifact_type : sprint_decision_log +status : draft +context_tier : T3 +updated_at : REPLACE_UPDATED_AT +summary_budget_lines : 140 +--- -Status: not started +# Sprint Decision Log ## Purpose -Use this file as the running sprint-level decision-memory surface. - -Keep the execution contract in `./sprint.md`, keep raw proof in `./evidence/`, -and use `./closeout.md` for end-of-sprint state. Use this file for the -meaningful decisions, reversals, constraints, and deferrals that occur while -the sprint is active. +Record sprint-scoped decisions, reversals, deferrals, and evidence pointers. ## Decisions -- Record important decisions as they happen. -- Capture the rationale, tradeoff, or non-obvious constraint that made the - decision worth preserving. +None yet. ## Reversals And Deferrals -- Record rejected paths, reversals, and explicit deferrals that later slices or - later sprints may need to understand. +None yet. ## Evidence Pointers -- Link to the most relevant files under `./evidence/`, touched files, or other - workflow artifacts when those links improve traceability. +Use `evidence/index.md` first when evidence exists. ## Carry Forward -- Record what later slices or later sprints should preserve, revisit, or - verify. +None yet. diff --git a/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/evidence/.gitignore b/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/evidence/.gitignore new file mode 100644 index 0000000..3fabd39 --- /dev/null +++ b/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/evidence/.gitignore @@ -0,0 +1,5 @@ +# Local scratch directories generated during sprint execution. +# Add project-specific scratch dirs here (e.g. /state/, /cache/, /runs/). +# Commit only reviewed, no-secret evidence files. +/state/ +/telegram-state/ diff --git a/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/evidence/.gitkeep b/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/evidence/.gitkeep deleted file mode 100644 index 2fa992c..0000000 --- a/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/evidence/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -keep diff --git a/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/evidence/index.md b/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/evidence/index.md new file mode 100644 index 0000000..cd217b0 --- /dev/null +++ b/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/evidence/index.md @@ -0,0 +1,47 @@ +--- +artifact_id : REPLACE_EVIDENCE_INDEX_ARTIFACT_ID +artifact_type : evidence_index +status : draft +context_tier : T4 +updated_at : REPLACE_UPDATED_AT +summary_budget_lines : 100 +--- + +# Evidence Index + +## State + +Replace with sprint status, date, and validation posture. + +## Validated Claims + +| Claim | Evidence | Gate | Status | Consumed By | +| --- | --- | --- | --- | --- | +| Replace with material claim. | Replace with evidence path or command pointer. | Replace with validation, live, or audit gate. | pending | Replace with closeout, index, roadmap, status, or `none`. | + +## Evidence Files + +| File | Type | Status | Open When | +| --- | --- | --- | --- | +| Replace with evidence path. | Replace with proof, validation, live, audit, or no-secret. | pending | Replace with specific read trigger. | + +## Live Gates And Deferred Evidence + +Separate required objective gates from optional, conditional, not-triggered, +out-of-scope, blocked, or operator-deferred checks. Required objective gates +must pass before the original sprint objective can close as passed. + +## Redaction And Retention + +No raw secrets, raw transcripts, raw prompts, raw model responses, raw file +content, or raw tool arguments unless an explicit debug-export policy allows it. + +## Promotion + +Replace with closeout or broader artifact pointer. + +## Read Policy + +Open this index for claim verification, validation audit, closeout review, or +regression investigation. Open focused evidence files only through a specific +claim or gate trigger. diff --git a/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/sprint.md b/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/sprint.md index b406126..e8e87f0 100644 --- a/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/sprint.md +++ b/.agents/skills/ub-workflow/assets/initiative-template/sprint-template/sprint.md @@ -1,149 +1,140 @@ -# Sprint PRD - -## Machine-Derived Context - -- Sprint: `REPLACE_SPRINT_TITLE` -- Goal: REPLACE_SPRINT_GOAL -- Depends on: `REPLACE_SPRINT_DEPENDS_ON` -- Validation focus: REPLACE_SPRINT_VALIDATION_FOCUS -- Evidence folder: `REPLACE_SPRINT_EVIDENCE_FOLDER` -- Planned subtasks: -REPLACE_SPRINT_SUBTASKS - -## Summary - -This sprint advances `REPLACE_SPRINT_TITLE` by pursuing the roadmap goal -`REPLACE_SPRINT_GOAL`. - -Use the machine-derived context above as the fixed starting point for the -sprint-specific plan below. +--- +artifact_id : REPLACE_SPRINT_ARTIFACT_ID +artifact_type : sprint_plan +status : draft +context_tier : T3 +updated_at : REPLACE_UPDATED_AT +summary_budget_lines : 480 +--- + +# Sprint: REPLACE_SPRINT_TITLE + +## Objective + +REPLACE_SPRINT_OBJECTIVE + +## Source + +- Accepted discovery or reviewed preview: REPLACE_SPRINT_SOURCE + +## Routing Preflight + +- Trigger categories considered: Replace with autonomy, authority, + runtime-boundary, policy, evidence, interoperability, agent-behavior changes, + agent loops, harnesses, loop continuation, goal judgment, budgets, + checkpoints, or `none`. +- Triggered categories: Replace with the triggered categories, or `none`. +- Fail-closed result: Replace with `discovery_required` when triggered + evidence may change route, contract, scope, validation, runtime boundary, or + implementation path; use `preview_ok` only when the route is already decided + and trigger evidence cannot change those decisions. + +## Discovery Triage + +- Outcome: Replace with `preview_ok`, `discovery_required`, + `operator_decision_needed`, or `not_triggered`. +- Outside evidence trigger: Replace with relevant standards, best practices, + official docs, current primary research, analogous systems, source packs, + user evidence, or operator evidence; use `not triggered` only with a + concrete reason. +- Trigger-presumed check: Replace with whether autonomy, authority, + runtime-boundary, policy, evidence, interoperability, or agent-behavior + changes are in scope. +- Promotion rule: If triage outcome is `discovery_required` or + `operator_decision_needed`, do not start implementation; create discovery or + get the operator decision first. + +## Why Preview Instead Of Discovery + +- Routing trigger: Replace with why the triage outcome permits preview, or + promote this candidate to discovery before implementation. +- Discovery trigger check: Replace with remaining route-changing + uncertainties, or `none`. +- Promotion rule: If preview work finds sequence, scope, appetite, product + direction, contract, runtime-boundary, or path-selection uncertainty, stop + and create discovery before start. + +## Product Increment Contribution + +- Contribution type: Replace with `direct`, `enabling`, or `audit`. +- Visible increment unblocked: Replace with the product increment this sprint ships or unblocks. +- Why not direct: Replace with reason if enabling or audit, otherwise `n/a`. +- Enabling-chain check: Replace with whether this is the second consecutive enabling or prerequisite sprint. + +## Bet Framing + +- Appetite: REPLACE_APPETITE +- Success evidence: REPLACE_SUCCESS_EVIDENCE +- Circuit breaker: REPLACE_CIRCUIT_BREAKER +- Non-goals: REPLACE_NON_GOALS +- Deferral path: REPLACE_DEFERRAL_PATH ## Scope -REPLACE_SPRINT_SCOPE_ITEMS - -## Execution Slices - -REPLACE_SPRINT_EXECUTION_SLICES +1. Replace with exact scope. -## Dependencies +## Scope Completion Rule -1. Roadmap dependency: `REPLACE_SPRINT_DEPENDS_ON` -2. Confirm any repository facts, prior sprint outputs, or external constraints - that materially affect execution before the sprint begins. -3. REPLACE_PREVIOUS_HANDOFF_NOTE +When this sprint uses words like `smallest`, `narrow`, or `only as needed`, +they mean the smallest objective-complete vertical slice. Every named owned +surface, required evidence gate, and exit criterion remains in scope unless +the operator explicitly changes the objective. -## Repository Truth At Sprint Start +## Operational Surface Preflight -1. Record the concrete repository truth this sprint depends on before - execution begins. -2. Capture the code, docs, tests, or metadata state that matters most. -3. Use pending handoff notes only when the previous sprint closeout can still - change what this sprint should assume. +- Triggered: Replace with `yes` or `no`. +- Surfaces: Replace with repo-owned operational surfaces introduced or changed, + or `none`. +- Owner and lifecycle: Replace with owner module/artifact and lifecycle, or + `not triggered`. +- Visibility and safety: Replace with user/operator/API visibility plus safety, + secrecy, policy, or authority rules, or `not triggered`. +- Inventory impact: Replace with inventory, topology, registry, route map, or + analogous owner document to update, or `none`. +- Validation path: Replace with tests, checks, live gates, or evidence proving + the surface, or `not triggered`. +- Promotion rule: If ownership, lifecycle, safety policy, validation, or + inventory impact may change scope, architecture, risk, or acceptance + criteria, promote discovery before execution. -## Chosen Path - -Write the sprint-specific implementation path here before execution begins. -Anchor it in the roadmap goal, validation focus, and current repository truth. - -## Rejected Alternative - -Record one rejected alternative with concise pros and cons before execution -begins. - -## Affected Areas +## Execution Slices -1. Record the likely affected files, modules, systems, or docs. -2. Add another affected area if needed. -3. Save sprint evidence under `REPLACE_SPRINT_EVIDENCE_FOLDER`. -4. Keep sprint-scoped execution decisions in `./decision-log.md`. +1. Replace with slice objective, acceptance, verification, dependencies, and likely touched areas. ## Validation Plan -1. Roadmap validation focus: REPLACE_SPRINT_VALIDATION_FOCUS. -2. Save sprint evidence under `REPLACE_SPRINT_EVIDENCE_FOLDER`. -3. Add concrete commands or checks for this sprint. -4. Add the documentation or synchronized-artifact checks required before this - sprint can close. -5. Add TG001-TG005 or equivalent deterministic test-signal checks when tests - will change. - -## Mode-Specific Start Checkpoint - -1. Record the active interaction mode for this sprint before execution begins. -2. Write the exact pre-sprint preview that should be surfaced to the user - before work starts, including an explicit statement that the sprint has not - started yet and what the sprint would do if started now. -3. If the active mode is `reviewed`, follow the canonical reviewed-mode - pre-sprint preview pattern defined in the `ub-workflow` - `workflow-contract.md` reference. -4. If the active mode is `reviewed`, record any question that changes the - sprint path before the explicit approval checkpoint. -5. If the active mode is `reviewed`, record the later explicit approval as the - event that starts execution and, when used, sets `sprint_start_ready: pass`; - do not create a second start prompt. -6. If the active mode is `reviewed` and the sprint is non-trivial, record at - least two plausible implementation paths with concise pros and cons plus a - recommended path marked `(*)`. -7. If the active mode is `reviewed` and the sprint is non-trivial, structure - the user-facing preview in this order: - `What Repo Truth Says`, `Inference`, `Implementation Paths`, - `Recommendation`, `Questions That Change The Sprint Path`, - then the explicit approval boundary. -8. If the active mode is `reviewed` and the sprint is non-trivial, do not - lead the preview with artifact-update or validation bookkeeping unless that - bookkeeping is itself the repo truth that materially changes the sprint. -9. If the active mode is `reviewed`, follow the shared `ub-authoring` - choice-question contract when questions are needed and preserve the same - decision structure inside the sprint preview. -10. If the active mode is not `reviewed`, record why a pre-execution stop is - not required for this sprint. -11. Record the expected post-execution reporting shape so the closeout can - recover it without relying on chat history. - -## Reviewability Check - -1. Confirm each execution slice is independently understandable. -2. Confirm each execution slice names acceptance and verification rather than - leaving success implicit. -3. Confirm dependencies and likely touched areas are explicit where they - materially affect planning or review. -4. Confirm the sprint plan is richer than the roadmap without simply copying - roadmap content verbatim. +1. Replace with concrete validation commands or checks. -## Exit Criteria +## Live Validation Matrix -1. The sprint-specific plan is concrete enough to execute without chat history. -2. The final validation requirements are explicit. -3. The documentation or synchronized-artifact completion requirement is - explicit. +| Gate | Status | Command | Credentials / env | Evidence path | Pass criteria | Redaction | +| --- | --- | --- | --- | --- | --- | --- | +| `provider_live_smoke` | out of scope | `n/a` | `n/a` | `n/a` | Not touched by this sprint. | No raw prompts, responses, secrets, or raw tool arguments. | +| `external_agent_live_probe` | out of scope | `n/a` | `n/a` | `n/a` | Not touched by this sprint. | No credentials, transcripts, prompts, or raw command arguments. | -## Final Audit Checklist +## User Or Operator Evidence -Use this checklist only when this sprint is the final audit sprint. +- Status: Replace with `used`, `not triggered`, or `deferred`. +- Evidence: Replace with user/operator input, operator decision, or `n/a`. +- Decision impact: Replace with how the evidence changes the sprint path, or why it does not. -- [ ] roadmap scope was actually executed or explicitly deferred -- [ ] no material work was silently skipped -- [ ] initiative-level validation is recorded and traceable -- [ ] relevant documentation and synchronized artifacts reflect the shipped behavior -- [ ] follow-up audit or refactor decisions were captured -- [ ] `retained-note.md` is ready to record the final state +## Reviewed-Mode Start Checkpoint -## Handoff Expectation +This sprint has not started yet. In reviewed mode, preview the path and wait +for later explicit approval before implementation. -1. Record what the next sprint should read first. -2. Record what the next sprint should do first. -3. REPLACE_NEXT_HANDOFF_NOTE +## Context Receipt -## Definition Of Done +Replace with loaded artifacts, skipped surfaces, source-pack fanout, and budget exceptions. -This sprint is done only when all of the following are true: +## Exit Criteria -1. planned functionality is complete or explicitly blocked -2. known in-scope issues are documented -3. required validation is run or explicitly deferred -4. relevant documentation and synchronized artifacts are updated or explicitly marked unchanged -5. validation evidence is recorded and traceable -6. governance bridge requirements are satisfied or explicitly marked not applicable -7. closeout is current and resumable -8. decision-log is current enough for the next sprint or final audit to trust it +1. Every accepted objective claim has fresh named passing proof. +2. Required validation and live gates pass after the final relevant change. +3. Evidence is routed through `evidence/index.md`, with required objective + gates separated from optional, not-triggered, blocked, out-of-scope, or + operator-deferred checks. +4. Required objective proof is not deferred while closing the original + objective as passed. +5. Decision log and closeout are current, including the closeout outcome and + learning review. diff --git a/.agents/skills/ub-workflow/assets/initiative-template/sprints/.gitkeep b/.agents/skills/ub-workflow/assets/initiative-template/sprints/.gitkeep deleted file mode 100644 index 2fa992c..0000000 --- a/.agents/skills/ub-workflow/assets/initiative-template/sprints/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -keep diff --git a/.agents/skills/ub-workflow/assets/lightweight-spec-template/spec.md b/.agents/skills/ub-workflow/assets/lightweight-spec-template/spec.md deleted file mode 100644 index 0c74f16..0000000 --- a/.agents/skills/ub-workflow/assets/lightweight-spec-template/spec.md +++ /dev/null @@ -1,63 +0,0 @@ -# Lightweight Spec - -## Snapshot - -| Field | Value | -| ----- | ----- | -| Spec | REPLACE_SPEC_NAME | -| Owner | REPLACE_OWNER | -| Created on | REPLACE_CREATED_ON | -| Interaction mode | `reviewed` | -| Status | REPLACE_SPEC_STATUS | -| Next action | REPLACE_NEXT_ACTION | - -## Summary - -Replace with a short summary of the bounded work this spec exists to shape. - -## Problem Or Opportunity - -1. Replace with the problem, opportunity, or gap this work addresses. -2. Replace with the repository or product context that makes the work matter. - -## Goals - -1. Replace with the main outcome this work must achieve. -2. Replace with any secondary bounded outcome that still belongs in this spec. - -## Non-Goals - -1. Replace with work that should stay out of scope. -2. Replace with anything that would require promotion into a full initiative. - -## Assumptions And Unknowns - -1. Replace with the assumptions that currently shape the plan. -2. Replace with the important unknowns or constraints that still need tracking. - -## Scale Decision - -1. Replace with why this is not just a direct bounded task. -2. Replace with why this does not yet require a full initiative, roadmap, and sprint pack. -3. Replace with the trigger that would promote this work into a full initiative. - -## Chosen Path - -Replace with the chosen implementation or planning path and why it is the best fit. - -## Rejected Alternative - -Replace with one rejected alternative and concise pros and cons. - -## Validation Plan - -1. Replace with the concrete checks, commands, or review steps that should prove the work is done. -2. Replace with any documentation or synchronized artifact checks that matter. - -## Documentation Touch Points - -1. Replace with the docs, guides, or contracts that will need updates if this work proceeds. - -## Next Action - -Replace with the next concrete step after this spec is reviewed. diff --git a/.agents/skills/ub-workflow/assets/operations-root/AGENTS.md b/.agents/skills/ub-workflow/assets/operations-root/AGENTS.md index 09589d6..fb52aef 100644 --- a/.agents/skills/ub-workflow/assets/operations-root/AGENTS.md +++ b/.agents/skills/ub-workflow/assets/operations-root/AGENTS.md @@ -1,53 +1,40 @@ -# Sprint Operations — AGENTS.md +# Workflow Agent Orientation -## Scope +Use the portable `ub-workflow` skill as the workflow contract. This file is a +thin operations-root reminder, not a duplicate rulebook. -Applies to this operations root and its descendants. +## Resume Order -## Local Rules - -- `operation-guide.md` is the formal workflow contract for this operations root. -- `roadmap.md` is the small live progress document for an initiative and should - be the first file read when resuming work. -- `spec.md` is the first file to read when resuming a lightweight spec root. -- Each sprint `sprint.md` must be a standalone sprint PRD that can be executed - without reopening the master `prd.md`. -- After importing a master PRD, stop and produce a durable `roadmap.md` before - initializing sprint folders. -- Initialize sprint folders only after `roadmap_ready: pass`. -- After sprint initialization, stop and wait for an explicit user request - before executing the active sprint. -- The roadmap must end with a final audit step before the initiative can close. -- Validation and documentation are completion gates, not optional follow-up work. -- Keep paths relative to the current operations root or initiative root when - practical. - -## Resume Order For Agents - -When resuming work inside one initiative root, read in this order: +1. `status.md` +2. `vision.md` only when product direction matters +3. root `options.md` for transition, future-work lookup, or option promotion +4. active `waves/wNN-*/wave.md` +5. active initiative or discovery named by status +6. initiative-local `options.md` for insertion, closeout, or transition checks -1. `./roadmap.md` -2. the most recent sprint `closeout.md` -3. the active or next sprint `sprint.md` -4. `./README.md` -5. `./prd.md` only if additional initiative-level context is still needed - -When resuming a lightweight spec root, read `./spec.md` first. - -## Update Discipline +## Local Rules -- Update `roadmap.md` whenever sprint status changes. -- Update the initiative `README.md` whenever phase, blockers, or next action changes. -- Keep `closeout.md` current before pausing or handing off. -- Do not initialize sprint folders until `roadmap.md` is complete enough to - stand in for plan output without chat history. -- Initialize sprint folders from the canonical `ub-workflow` sprint template - when building the roadmap-derived sprint set. -- Execute only the user-requested active sprint in one invocation, then stop - after closeout and roadmap updates. -- Do not treat a sprint as complete until its validation results, evidence, and - relevant documentation updates are recorded or explicitly marked unchanged. -- Do not treat an initiative as complete until final validation, retained-note, - and documentation synchronization checks are recorded. -- Before treating an initiative as complete, record whether the user wants any - follow-up audits or refactors. +- Keep status compact and current. +- Update status by replacing current facts, not by appending chronology. +- Use root `options.md` for curated product-level, future-wave, and + unknown-owner options. It is pre-commitment memory, not a backlog ledger or + execution queue. +- Use initiative-local `options.md` only for possible insertions before that + initiative closes. +- Remove options after promotion, rejection, merge, or completion once the + receiving artifact owns the durable trace. Do not maintain a `Done` lane. +- Run `scripts/check_workflow_options.py` from the shared `ub-workflow` skill + during wave activation, initiative closeout, terminal audit, option + promotion, and sprint preview from an option. +- Store detail in the owner artifact. +- Do not execute a sprint without accepted discovery or reviewed preview. +- When forecast pressure appears, present options and tradeoffs, then wait for + explicit operator decision before cutting, deferring, rerouting, or buying + more scope. +- Keep one active sprint and one active discovery per active initiative unless + status records an explicit exception. +- Before activating a new wave or initiative, review root options and + unresolved local options from the closing initiative. +- Structural workflow changes that affect artifact ownership, lifecycle gates, + scaffolding, transition policy, or recovery context need a compact accepted + workflow-improvement decision record. diff --git a/.agents/skills/ub-workflow/assets/operations-root/README.md b/.agents/skills/ub-workflow/assets/operations-root/README.md deleted file mode 100644 index 942de46..0000000 --- a/.agents/skills/ub-workflow/assets/operations-root/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# Initiative Index - -This directory is the canonical initiative index for work managed under the -repository operations root. - -Start with `operation-guide.md` for the durable workflow SOP, then open the -initiative root you want to work on. - -Use each initiative's `roadmap.md` as the small live progress document when -resuming work. - -If you want to bootstrap a new initiative quickly, use -`uv run python .agents/skills/ub-workflow/scripts/scaffold_initiative.py create --prd-source `, replacing `uv run python` with the host repository's local Python runner when `uv` is unavailable. - -If you want a bounded planning artifact without opening a full initiative, use -`uv run python .agents/skills/ub-workflow/scripts/scaffold_initiative.py create-spec `, replacing `uv run python` with the host repository's local Python runner when `uv` is unavailable. - -## Active Initiative Roots - -REPLACE_ACTIVE_INITIATIVE_ROOTS - -## Active Lightweight Specs - -REPLACE_ACTIVE_LIGHTWEIGHT_SPECS - -## Current State - -1. The operation guide lives here as the canonical SOP for initiative work. -2. The scaffold helper can bootstrap the parent operations root and create new initiative roots or lightweight specs on demand. -3. The scaffold helper uses the skill's internal initiative, lightweight-spec, and sprint templates instead of requiring copied local scaffolding directories. -4. Historical initiative roots live under `../archive/`. diff --git a/.agents/skills/ub-workflow/assets/operations-root/operation-guide.md b/.agents/skills/ub-workflow/assets/operations-root/operation-guide.md index 427944c..7e880cd 100644 --- a/.agents/skills/ub-workflow/assets/operations-root/operation-guide.md +++ b/.agents/skills/ub-workflow/assets/operations-root/operation-guide.md @@ -1,236 +1,50 @@ -# Initiative Operation Guide +# Workflow Operation Guide - -## Purpose +This guide summarizes the portable `ub-workflow` operating model. -This document defines a strict, reusable standard operating procedure for large -or risky initiatives that cannot be executed reliably from chat history alone. - -Use this SOP when work requires: - -1. planning and R&D before implementation -2. a self-contained PRD that can be executed later -3. multiple stop-and-resume execution sprints -4. deterministic evidence and explicit gate states -5. a durable retained summary after completion - -This SOP is written to be usable by a PM, an engineer, and an AI agent with the -same source of truth. - -## Typical Ownership Model - -The most common workflow is: - -1. a human authors the initial PRD -2. a human or AI agent scaffolds a dated initiative root and copies that PRD into `./prd.md` -3. a human or AI agent refines the PRD and produces a durable `roadmap.md` -4. the human reviews and explicitly approves the roadmap -5. sprint-pack preparation happens only after the roadmap is approved -6. sprint folders are initialized only after the roadmap is approved when directory materialization is needed -7. the workflow stops until the human explicitly requests the active sprint -8. execution happens one sprint at a time, with a human review checkpoint after each sprint, until the initiative is complete - -This SOP supports other authorship patterns, but it assumes the initial product -or engineering intent has a clear human owner. - -## When To Use This SOP - -Use this SOP for work that has at least one of these properties: - -1. spans more than one working session -2. changes behavior, architecture, or operating model -3. needs explicit option analysis or governance review -4. needs evidence-backed handoffs between sprints -5. must be resumable without relying on prior chat context - -Do not use this SOP for small, single-session fixes where a lightweight task -note is enough. - -Before starting this SOP, make a scale decision: - -1. direct bounded task when no durable planning artifact is needed -2. lightweight spec under `./specs/YYYY-MM-DD-slug/spec.md` when the work - needs a written contract but not a roadmap and sprint pack -3. initiative under `./initiatives/YYYY-MM-DD-slug/` when the work needs a - PRD, roadmap, and resumable sprint execution - -## Non-Negotiable Rules - -1. One initiative uses one initiative root directory. -2. The PRD must be self-contained and execution-ready before sprinting starts. -3. Every sprint must be stop-resume safe. -4. Evidence, planning, and closeout are separate artifacts. -5. Gate states are always `pass`, `fail`, or `blocked`. -6. Exceptions must be explicit, temporary, and owned. -7. The retained note is the durable record after completion. -8. Chat history is never the system of record. - - - -## Operating Model - -This SOP defines a six-phase lifecycle. - -### Phase 1: Plan And Author The PRD - -Goal: turn research and intent into one self-contained PRD that is ready to be -executed later by a different operator or agent. - -### Phase 2: Plan And Approve The Roadmap - -Goal: turn the approved PRD into one durable roadmap that can initialize sprint -folders without relying on chat history. - -### Phase 3: Prepare The Sprint Pack - -Goal: turn the approved roadmap into execution-ready sprint PRDs before any -implementation begins. - -### Phase 4: Initialize Sprint Directories - -Goal: materialize or repair sprint directories without conflating scaffolding -with sprint execution. - -### Phase 5: Execute In Ordered Sprints - -Goal: split the PRD into bounded sprints that can be paused, resumed, audited, -and handed off without loss of context. - -### Phase 6: Final Audit And Durable Retention - -Goal: finish the roadmap with a mandatory final audit, confirm completeness and -synchronization, ask for any follow-up audits or refactors, then replace bulky -temporary execution detail with a concise retained note. - -## Lifecycle Gates - -This SOP uses lifecycle gates in addition to any repository-specific merge or -release gates. - -| Gate | Meaning | Allowed States | -| ---------------------- | ------------------------------------------------------------------------ | ------------------------- | -| `prd_ready` | The PRD is execution-ready and sprint planning may begin | `pass`, `fail`, `blocked` | -| `roadmap_ready` | The roadmap is execution-ready and sprint preparation may begin | `pass`, `fail`, `blocked` | -| `sprint_content_ready` | The sprint pack is execution-ready and sprint start readiness may begin | `pass`, `fail`, `blocked` | -| `sprint_start_ready` | Context refreshed; reviewed-mode post-preview approval is recorded | `pass`, `fail`, `blocked` | -| `sprint_closeout` | A sprint has enough evidence and handoff detail to pause or continue | `pass`, `fail`, `blocked` | -| `archive_ready` | The final audit output is ready for explicit archive review | `pass`, `fail`, `blocked` | -| `initiative_complete` | The initiative has a retained note and a validated completion baseline | `pass`, `fail`, `blocked` | - -`roadmap_ready: pass` is human-owned in this workflow. The agent may recommend -approval after surfacing the roadmap review checklist, but the human must -explicitly approve the roadmap before that gate is set. - -State intent: - -- `pass`: required controls are satisfied -- `fail`: the work was evaluated and one or more required controls failed -- `blocked`: required controls cannot be satisfied yet because prerequisites, - evidence, or approvals are missing - - - -## Canonical Directory Layout - -Store every initiative or lightweight spec under one canonical root. - -## Path Portability Rules - -Write all operational instructions relative to the current operations root when -possible. - -Preferred path style inside this SOP and inside initiative files: - -1. from this initiative index, use `./-/...` -2. from an initiative root, use `./prd.md`, `./sprints/`, `./retained-note.md` -3. use repo-root-relative paths only when referencing legacy material outside - the current operations root - -Generic pattern: +## Model ```text -/ - archive/ - initiatives/ - AGENTS.md - README.md - operation-guide.md - -/ - AGENTS.md - README.md - prd.md - roadmap.md - research/ - sprints/ - 01-/ - sprint.md - closeout.md - evidence/ - ./ - 2026-03-27-example-initiative/ - exceptions/ - retained-note.md - specs/ - -/ - spec.md +Product Vision -> Product Options -> Outcome Waves -> Initiatives -> Discoveries -> Sprints ``` -The generated operations root does not need a checked-in `initiative-template/` -copy. The scaffold helper uses the skill's internal canonical templates to -create initiative roots and sprint skeletons on demand. - -## Directory Contract - -### `README.md` - -The operator-facing status file for the initiative root. - -Use it as the root summary and entry point. - -`roadmap.md` is the smaller live progress document. - -### `prd.md` - -The self-contained initiative definition. It must remain understandable without -opening research or sprint files. - -### `research/` - -Optional source captures, exploratory notes, and supporting material from the -planning phase. The PRD may cite it, but must not depend on it for core intent. - -### `sprints/` +## WIP -The execution packs. Each sprint gets its own numbered directory so planning, -evidence, and closeout stay co-located. +Default active WIP is one delivery sprint and one discovery per active +initiative. Wave discovery is active only for activation, transition, or +reroute. -Use the canonical `ub-workflow` sprint template when initializing all sprint -directories from the master roadmap. Do not initialize sprint directories until -`roadmap_ready: pass`. -Initialization prepares execution; it does not start sprint work automatically. +## Advancement -### `exceptions/` +1. Refresh status and active pointers. +2. Revalidate stale candidates before delivery. +3. Create or accept discovery when path truth is uncertain. +4. Prepare only the active or next sprint. +5. In reviewed mode, preview first and wait for later approval. +6. When scope pressure appears, present options and tradeoffs before any + operator decision to cut, defer, reroute, or buy more scope. +7. Close with evidence, outcome and learning review, Forecast Delta, + mini-retro, and next action. -Optional explicit exception records. If no exceptions are active, this folder -may be omitted. +## Options Boards -### `retained-note.md` +Future work may live in root or initiative-local options boards before +commitment. Options are ordered by document order within horizon lanes, but +they are not delivery commitments, status ledgers, or execution queues. -The durable completion record for the initiative. +Remove an option after it is promoted, rejected, merged, or completed and the +receiving artifact owns the durable trace. Do not maintain a `Done` lane in +options boards. -### `specs/` +Run `scripts/check_workflow_options.py` during wave activation, initiative +closeout, terminal audit, option promotion, and sprint preview from an option. -Optional lightweight planning roots for work that is bigger than a direct task -but smaller than a full initiative. +Structural workflow changes that affect artifact ownership, lifecycle gates, +scaffold output, transition policy, or recovery context need a compact +accepted workflow-improvement decision record. -## Naming Rules +## Source Routing -1. Initiative roots use `YYYY-MM-DD-slug`. -2. Sprint directories use `NN-slug` with zero-padded ordering. -3. Evidence directories live inside the owning sprint directory. -4. Singular control files keep fixed names: `README.md`, `AGENTS.md`, `prd.md`, - `roadmap.md`, `retained-note.md`, `sprint.md`, and `closeout.md`. -5. Do not scatter PRDs, evidence, and retained notes across unrelated folders. -6. Prefer relative paths inside operation artifacts unless cross-root references - are necessary. - +Project-root `SOURCE_ATLAS.md` routes source-code work. Bootstrap seeds it once +from visible project roots; later updates happen only when source boundaries or +test topology change. diff --git a/.agents/skills/ub-workflow/references/artifact-contracts.md b/.agents/skills/ub-workflow/references/artifact-contracts.md index 79c9992..fd9ae2c 100644 --- a/.agents/skills/ub-workflow/references/artifact-contracts.md +++ b/.agents/skills/ub-workflow/references/artifact-contracts.md @@ -1,274 +1,322 @@ # Artifact Contracts -Use these files as the minimum contract for reusable initiative and -lightweight-spec workflow surfaces. - -## Required Initiative Files - -- `README.md`: root resume surface and current status -- `AGENTS.md`: local resume order and update discipline -- `prd.md`: self-contained initiative definition -- `roadmap.md`: small live tracker with full sprint order -- `rollup.md`: readable cross-sprint summary and carry-forward surface -- `retained-note.md`: durable completion summary -- `research/`: optional supportive discovery notes, kept secondary to the main - workflow artifacts -- `exceptions/`: optional bounded exception records, not a catch-all note - store -- `sprints/`: execution directories and the default home for sprint-local - evidence and sprint-local decision memory - -## `README.md` +Use these contracts when creating or validating portable `ub-workflow` +artifacts. + +## Project Root Companions + +Required project-root files: + +1. `AGENTS.md` +2. `SOURCE_ATLAS.md` + +`AGENTS.md` owns the repo-local agent overlay. `SOURCE_ATLAS.md` owns source +routing and is seeded once during bootstrap from visible project roots. Later +updates are event-based when source boundaries, package lanes, or test +topology change. + +## Operations Root + +Required root files: + +1. `vision.md` +2. `options.md` +3. `status.md` +4. `WORKFLOW_ATLAS.md` +5. `SOURCE_PACK_ATLAS.md` +6. `AGENTS.md` + +Operations-root files should be compact. Detailed workflow rules belong in +this skill; repo overlays should point here instead of copying the whole +contract. + +Artifact frontmatter, `context_tier`, `summary_budget_lines`, context receipts, +retained-context reads, evidence index shape, and broader writeback receipts are +defined in `references/context-management.md`. Trace IDs, tags, trace routes, +and owner-only trace-token policy are defined in `references/trace-tokens.md`. + +## `vision.md` Minimum sections: -1. initiative name and owner -2. active interaction mode -3. current phase -4. current gate state -5. roadmap status -6. active sprint or `none` -7. last completed sprint -8. next step -9. blockers -10. governance bridge level and profile when applicable -11. validation pointers -12. smallest file set needed to resume - -## `prd.md` +1. product promise; +2. audiences; +3. durable principles; +4. capability pillars; +5. evidence questions; +6. change rule. + +## Root `options.md` Minimum sections: -1. summary -2. background or problem statement -3. goals -4. non-goals -5. scope -6. principles -7. current-state diagnosis -8. option analysis with chosen path and one rejected alternative -9. success criteria -10. validation expectations -11. documentation touch points -12. governance bridge selection when applicable -13. dependencies and constraints -14. execution risks -15. readiness checklist +1. board rules; +2. next-wave candidate lane; +3. probable-later-wave lane; +4. unassigned product option lane; +5. update rules. -## `roadmap.md` +Every active option card must include: + +1. suggested home; +2. assignment confidence; +3. evidence links; +4. why it matters; +5. promotion trigger; +6. revalidation rule; +7. last reviewed date. + +Options boards are not ledgers. Do not add `Done`, `Completed`, `Closed`, or +archive-style lanes. Remove option cards after promotion, rejection, merge, or +completion once the receiving artifact owns the durable trace. + +## `status.md` Minimum sections: -1. roadmap objective -2. PRD scope summary -3. overall initiative checklist -4. sprint sequence with one entry per sprint, where every sprint entry declares path, goal, dependencies, validation focus, subtasks, and evidence folder -5. dependency chain across sprints -6. validation focus per sprint -7. current position and next action -8. stop-resume handoff expectation -9. completion condition -10. final audit as the last item +1. current product posture; +2. current operating state; +3. WIP state; +4. active pointers; +5. blockers; +6. wave sequence; +7. conditional candidate tracks; +8. retained-context routes; +9. next allowed action. -Current-position rule: +Avoid chronological ledgers, broad reading queues, and sprint history. Update +owned facts by replacement. -1. record the persisted interaction mode alongside current sprint state +## `wave.md` -Roadmap shape rules: +Minimum sections: -1. Use as many implementation sprints as the PRD actually requires; do not imply a two-sprint cap. -2. Number implementation sprints sequentially as `Sprint 01` through `Sprint NN`. -3. Keep the final audit as the terminal roadmap item after all implementation sprints. -4. Use `roadmap.md` as the durable post-plan artifact that unlocks sprint initialization. -5. Keep roadmap status explicit enough to distinguish `not started`, `planned`, `generated`, and `complete` when those states matter. +1. outcome; +2. status; +3. why now; +4. scope boundaries; +5. bet framing at wave scale; +6. forecast and appetite; +7. non-goals; +8. success evidence; +9. outcome signals; +10. initiative map; +11. retained inputs; +12. transition and reroute rules. + +## `initiative.md` -## `sprint.md` +Minimum sections: -Each sprint document must stand alone. +1. summary; +2. outcome bet; +3. appetite; +4. success evidence; +5. circuit breaker; +6. forecast and appetite; +7. outcome signals; +8. goals and non-goals; +9. constraints; +10. durable decisions; +11. current status; +12. index pointers. + +## Initiative `options.md` -Treat each `sprint.md` as an execution-ready sprint PRD, not as a starter -shell. +Minimum sections: + +1. board rules; +2. possible initiative insertion lane; +3. deferred-to-product-options lane; +4. update rules. + +Every active local option card uses the same fields as root option cards. +Before initiative closeout, every local option must be promoted, moved to root +options, rejected, or removed as obsolete. + +## `roadmap.md` Minimum sections: -1. sprint objective -2. exact scope -3. execution slices -4. dependencies -5. verified repository truth at sprint start -6. chosen implementation path -7. one rejected alternative with concise pros and cons -8. affected files, modules, systems, or docs -9. validation plan -10. mode-specific start checkpoint -11. reviewability check -12. exit criteria -13. final-audit checklist for the final audit sprint -14. handoff expectation -15. definition of done - -Sprint document rules: - -1. The active or next sprint must be readable and actionable without reopening - the full initiative chat history. -2. Placeholder-only sprint shells are incomplete planning state, not - execution-ready artifacts. -3. Execution slices should be the main place where planned work is broken into - independently reviewable chunks. -4. Each execution slice should name acceptance, verification, dependencies, - and likely touched areas when those details materially affect execution or - review. -5. Later sprints may contain named pending handoff markers only in fields that - legitimately depend on prior closeout truth. -6. The validation plan must be concrete enough for another operator to execute - it without improvising missing checks. -7. The handoff expectation must name what the next sprint should read first. -8. Use `decision-log.md` for evolving sprint-time decisions, reversals, and - deferrals instead of forcing all running memory into `closeout.md`. -9. When the active interaction mode is `reviewed`, the sprint document must - make the pre-sprint preview, option questions when needed, approval - boundary, and expected post-execution reporting shape easy to recover. -10. For non-trivial reviewed-mode sprints, the mode-specific start checkpoint - should preserve the richer counterfactual analysis in recoverable order: - `What Repo Truth Says`, `Inference`, `Implementation Paths`, - `Recommendation`, then any structured fallback questions needed before - sprint start approval. -11. For non-trivial reviewed-mode sprints, artifact-update or validation - bookkeeping may appear in the checkpoint, but it should not be the lead - user-facing content unless it is itself the repo truth that materially - shapes the sprint. +1. objective; +2. current position; +3. forecast control; +4. active or next sprint route; +5. adaptive plan, candidate route, or options pointer; +6. sequence changes; +7. revalidation rules; +8. pre-audit continuation window; +9. final audit candidate; +10. update rules. + +The roadmap is an adaptive strategy map, not a token ledger. Discovery-driven +insertions, splits, reroutes, and deferrals must be promoted here before the +discovery is accepted. Closeout-driven next-route changes must be promoted +here before sprint closeout passes. + +Registered candidate briefs belong in the roadmap because they are live route +and forecast intent. Keep evidence routes and trace lookup in `index.md`. + +Forecast And Appetite records appetite, forecast range/count, confidence, +throughput basis, known unknowns, operator-choice scope hammers, and expansion +trigger. Forecast Control records completed count, registered remaining, +forecast delta, appetite state, and next scope tradeoff. Expansion beyond +appetite must show the operator decision to cut/defer, reroute, or buy more. + +## `index.md` -## `decision-log.md` +Minimum sections: + +1. current snapshot; +2. forecast snapshot; +3. durable direction; +4. artifact routes; +5. meaningful accepted discoveries; +6. completed sprints and evidence indexes; +7. trace routes; +8. supersession notes; +9. update rules. + +The index is the triggered T3 compact lookup and durable-history surface. It +replaces separate initiative rollups and artifact indexes. It should not own +live candidate briefs, active route decisions, or current forecast control. -Use this file as the running sprint-level decision-memory surface. +## Discovery Briefs + +Wave discovery path: `waves/wNN-*/discoveries/wNN-dNN-slug.md`. +Initiative discovery path: +`waves/wNN-*/initiatives/iNN-*/discoveries/wNN-iNN-dNN-slug.md`. Minimum sections: -1. purpose -2. decisions -3. reversals and deferrals -4. evidence pointers -5. carry forward +1. question; +2. context receipt; +3. repo truth; +4. user or operator evidence status; +5. outside research, standards, official docs, current primary research, or + best-practice comparison when relevant; +6. source-pack or analogous-system comparison when relevant; +7. options; +8. recommendation; +9. forecast impact when sequence changes; +10. risk and stop conditions; +11. validation expectations; +12. decision slot. + +Forecast Impact is required when a discovery or reviewed preview changes +sequence. It must state one of `fits appetite`, `cuts/defers scope`, +`requires operator buy-more`, or `reroutes/stops`. -Decision-log rules: +## `sprint.md` -1. Keep the log sprint-scoped; repository-level durable decisions still belong - in `docs/adr/` only when ADR escalation is actually warranted. -2. Record rationale, changed direction, or non-obvious constraints here while - the sprint is active instead of relying on post-hoc reconstruction in - `closeout.md`. -3. Link to sprint `evidence/`, touched files, or synchronized artifacts when - those links materially improve resumability. -4. Keep the file readable; it is a high-signal running log, not a raw command - dump. +Minimum sections: -## `closeout.md` +1. objective; +2. accepted discovery or reviewed preview source; +3. fail-closed Routing Preflight before choosing preview; +4. discovery triage before claiming discovery is unnecessary; +5. why preview instead of discovery when the source is a reviewed preview; +6. product increment contribution; +7. bet framing; +8. exact scope; +9. execution slices; +10. affected areas; +11. operational surface preflight when triggered; +12. Project Evolution Gate when triggered; +13. validation plan; +14. Live Validation Matrix; +15. user or operator evidence status; +16. reviewed-mode start checkpoint when active; +17. context receipt; +18. exit criteria. + +Operational surface preflight is triggered when a sprint introduces or changes +a repo-owned surface that future operators, users, code, tools, agents, or +integrations may rely on. Operational surfaces include, when present: +persisted files, caches, logs, queues, databases, generated artifacts, +configuration, secrets-adjacent state, network endpoints, background jobs, +scheduled tasks, public API facets, CLI commands, UI routes, plugin extension +points, telemetry streams, and external integrations. The sprint preview must +identify the surface owner, lifecycle, visibility, safety policy, validation +path, and whether an existing inventory, topology, registry, route map, or +analogous owner document must be updated. If ownership, lifecycle, safety +policy, validation, or inventory impact is unclear enough to change scope, +architecture, risk, or acceptance criteria, promote discovery before +execution. + +When `sprint.md` uses words like `smallest`, `narrow`, or `only as needed`, +the artifact must make clear that they mean the smallest objective-complete +vertical slice. Every named owned surface, required evidence gate, and exit +criterion remains in scope unless the operator explicitly changes the +objective. + +## `decision-log.md` Minimum sections: -1. `environment_note` -2. `scope_note` -3. `decision_note` -4. `gate_note` -5. `exception_note` -6. `validation_note` -7. `done_verification_note` -8. `handoff_note` -9. `follow_up_note` -10. `post_execution_summary_note` - -Closeout structure rules: - -1. `gate_note` must record the initiative workflow gate state. -2. When governance is active, `gate_note` must also record the governance gate type and result. -3. `validation_note` must capture commands, outcomes, evidence pointers, and documentation-sync status. -4. When governance is active, `exception_note` must reference canonical governance exception metadata. -5. When a sprint used `decision-log.md`, the closeout should leave it current - enough for the next sprint or final audit to trust it. -6. When the active interaction mode exposes user-facing post-execution - reporting, the closeout should make considerations moving forward, - assumptions made, and things to watch easy to recover for later reporting. -7. When the active interaction mode exposes user-facing post-execution - reporting, `post_execution_summary_note` should be readable enough to reuse - directly as the user-facing post-sprint summary. - -## `rollup.md` - -Use this file as the readable initiative-level summary across sprints. +1. purpose; +2. decisions; +3. reversals and deferrals; +4. evidence pointers; +5. carry forward. + +## `closeout.md` Minimum sections: -1. purpose -2. current snapshot -3. major decisions -4. sprint highlights -5. cross-sprint risks and deferrals -6. validation and evidence rollup -7. research and exceptions pointers - -Rollup rules: - -1. Keep `rollup.md` shorter and easier to scan than walking every sprint - directory one by one. -2. Summarize cross-sprint decisions, reversals, and major validation signals - here, then point to the owning sprint `decision-log.md`, `closeout.md`, or - `evidence/` when more detail is needed. -3. Do not duplicate every sprint detail verbatim; the rollup is a readable - index, not a second full archive. -4. Keep `research/` and `exceptions/` visibly secondary by pointing to them - only when they truly contain cross-sprint discovery or bounded exception - records. - -## `retained-note.md` +1. outcome summary; +2. outcome and learning review; +3. forecast delta; +4. evidence pointer; +5. validation result; +6. broader writeback decisions; +7. Project Evolution Gate result when triggered; +8. mini-retro; +9. handoff; +10. next recommendation. + +## `evidence/index.md` Minimum sections: -1. outcome -2. what shipped -3. preserve these decisions -4. useful future notes -5. deferred items -6. follow-up decisions -7. validation baseline - -Retained-note rules: - -1. When governance is active, record governance bridge level, profile, exception refs, and ADR refs. -2. Validation baseline must be traceable enough for a later operator to reconstruct the final audit posture. -3. Do not pre-fill initiative-specific decisions during scaffold creation; keep the retained note minimal until final audit work begins. - -## Lightweight Spec Root - -Use lightweight specs for work that sits between direct bounded execution and a -full initiative. - -Path contract: - -- `./specs/YYYY-MM-DD-slug/spec.md` - -Minimum `spec.md` sections: - -1. snapshot -2. summary -3. problem or opportunity -4. goals -5. non-goals -6. assumptions and unknowns -7. scale decision -8. chosen path -9. one rejected alternative with concise pros and cons -10. validation plan -11. documentation touch points -12. next action - -Lightweight spec rules: - -1. The spec must be self-contained enough for another operator to continue - without chat history. -2. The spec must explain why the work is not merely a direct bounded task and - why it does not yet require a full initiative. -3. The spec must record what would trigger promotion into a full initiative. -4. The active interaction mode must be explicit in the lightweight spec - snapshot. -5. Lightweight specs do not require `roadmap.md`, sprint scaffolding, or - retained-note flow by default. +1. state; +2. validated claims; +3. evidence files; +4. required objective gates and optional or deferred evidence; +5. redaction and retention; +6. promotion; +7. read policy. + +The evidence index is a claim-to-proof router. It should let a future reader +verify every material closeout result, validation claim, and route-changing +learning without loading raw evidence by default. It does not own the sprint +narrative, outcome review, mini-retro, or trace tokens. + +Required objective gates must be labeled separately from optional, +not-triggered, blocked, out-of-scope, or operator-deferred checks. A required +objective gate cannot be operator-deferred while the original sprint objective +closes as passed. + +Outcome Signals, Forecast And Appetite, Forecast Control, Forecast Impact, +Product Increment Contribution, Forecast Delta, user/operator evidence status, +decision latency, and retro evidence checks belong in the owning wave, +initiative, roadmap, discovery, sprint, or closeout surfaces. +They must not create a separate metrics, forecast, trace, or retro atlas. + +Sprint evidence folders include a `.gitignore` for generated runtime scratch +state. Treat any project-specific scratch directories listed there as local +scratch unless a reviewed export policy explicitly promotes a redacted +subset to committed evidence. + +## Source Packs + +Source-pack roots use `YYYY-MM-DD-slug/` and include `00-readme.md`. + +The readme states: + +1. status; +2. creation or migration date basis; +3. read triggers; +4. do-not-read triggers; +5. default section limit; +6. promotion rule. diff --git a/.agents/skills/ub-workflow/references/context-management.md b/.agents/skills/ub-workflow/references/context-management.md new file mode 100644 index 0000000..cf3cac0 --- /dev/null +++ b/.agents/skills/ub-workflow/references/context-management.md @@ -0,0 +1,317 @@ +# Context Management + +Use this reference when interpreting context tiers, read budgets, atlas routing, +frontmatter, receipts, retained-context reads, evidence routing, or broader +writeback decisions. + +## Purpose + +Workflow context management keeps durable workflow artifacts useful without +turning every resume into a full archive read. It defines what must be loaded +by default, what is conditional, and what stays retained until a concrete +trigger makes it relevant. + +## Core Rule + +Retrieval proposes context. Owner artifacts commit durable truth. + +Do not treat search results, source packs, old closeouts, or raw evidence as +live operating state. Promote only the facts that change current direction into +the current owner: `status.md`, `vision.md`, `wave.md`, `initiative.md`, +`roadmap.md`, `index.md`, or the active sprint pack. + +## Design Basis + +The tier model is a `ub-workflow` retrieval policy, not an external industry +standard. It exists to apply common product and documentation principles: + +1. make important work visible enough for inspection and adaptation; +2. keep policies explicit, sparse, simple, visible, and easy to revise; +3. reduce work in progress and context switching by loading only the context + needed for the current decision; +4. optimize documentation for clarity, findability, and reliability; +5. record meaningful decisions with enough context to avoid repeating the same + debate later. + +Use the least context that preserves truth. Exceed the normal read set when the +work needs it, then record why. + +Context tiers may change over an artifact's lifecycle. Draft or active +discoveries and sprint packs are normally T2. Accepted discoveries, passed +sprint packs, closeouts, decision logs, and initiative indexes are normally T3 +because they are triggered lookup and history surfaces, not routine route +steering surfaces. + +## Context Tiers + +| Tier | Name | Default load | Examples | Use | +| --- | --- | --- | --- | --- | +| T0 | Startup spine | Yes | root `AGENTS.md`, `.ub-workflows/status.md`, compact current state, `vision.md` when product direction matters | Resume orientation and next allowed action | +| T1 | Route maps and policy | Conditional | `WORKFLOW_ATLAS.md`, `SOURCE_PACK_ATLAS.md`, `SOURCE_ATLAS.md`, this reference | Decide where to look and which contract applies | +| T2 | Active work package | Conditional | active `wave.md`, `initiative.md`, `roadmap.md`, active discovery, active sprint pack | Execute or steer current work | +| T3 | Retained memory | Triggered | initiative `index.md`, source packs, retained notes, accepted discoveries, passed sprint packs, old closeouts | Recover background without polluting startup | +| T4 | Detailed evidence | Triggered | evidence indexes, validation records, live-smoke notes, audit logs | Verify specific claims | +| T5 | Raw or archive detail | Rare | raw logs, long transcripts, archived research, original captures | Inspect only when necessary and safe | + +## Atlas Roles + +`WORKFLOW_ATLAS.md` routes workflow artifacts: waves, initiatives, +discoveries, sprints, current owners, initiative indexes, and retained +workflow notes. + +`SOURCE_PACK_ATLAS.md` routes retained research packs. Search the atlas before +opening source packs, then open the pack readme before any detailed section. + +`SOURCE_ATLAS.md` routes project source code. It is created during bootstrap by +a one-time scan, then updated only when source boundaries, package lanes, or +test topology change. + +## Phase Read Budgets + +These are steering budgets, not hard caps. If a phase needs more, record a +budget exception in the context receipt. + +| Phase | Normal read set | Warn when | +| --- | --- | --- | +| Resume | T0 plus directly named files | More than 5 files | +| Workflow artifact work | T0, relevant atlas, active owner, touched artifact | More than 10 files | +| Discovery creation | T0, owner artifacts, routed source/source-pack context | More than 12 files or more than 3 source-pack files | +| Sprint preview | Accepted discovery or route, owner artifacts, target source routes | More than 10 files before source verification | +| Sprint implementation | Sprint pack plus routed source/tests | Broad source traversal lacks a route reason | +| Sprint closeout | Sprint pack, evidence index, changed owners | Broader writebacks lack owner-change reasons | +| Final audit | Roadmap, triggered index, retained note, latest closeouts, evidence summaries, wave criteria | Startup owners are reread without a routing reason | +| Wave transition | Status, current wave, next wave candidate, latest index/closeout, vision if direction changes | Source packs are read without a transition trigger | + +## Frontmatter Contract + +Current workflow artifacts should start with compact metadata: + +```yaml +--- +artifact_id : w11-i01-d01-example +artifact_type : discovery_brief +status : draft +context_tier : T2 +updated_at : 2026-05-28 +summary_budget_lines : 24 +--- +``` + +Fields: + +1. `artifact_id`: stable local identifier, usually matching wave, initiative, + discovery, or sprint IDs. +2. `artifact_type`: portable role of the artifact. +3. `status`: current lifecycle state for this artifact, not project state. +4. `context_tier`: retrieval tier from T0 through T5. +5. `updated_at`: last meaningful owner update date. +6. `summary_budget_lines`: expected compact-read size for summaries and + resumes. It is role-based advisory retrieval metadata, not a hard lint gate, + full-file ceiling, or truncation instruction for validation reads. + +## Budget Calibration + +Use role-based budget bands instead of forcing every artifact toward the same +size: + +1. product vision: generous enough for the full editable product PRD; +2. status and route maps: compact enough for routine startup or routing; +3. wave and initiative charters: concise owner truth, not chronology; +4. roadmaps: enough for live route, forecast control, and candidate briefs; +5. initiative indexes: triggered lookup/history, not route planning; +6. discoveries and sprint plans: enough for decision context and execution + detail after a routed trigger; +7. closeouts and decision logs: enough for result, learning, and carry-forward; +8. evidence indexes and proof notes: enough for claim verification. + +Line budgets may be above current line count when the artifact intentionally +has room to grow within its role. If an artifact regularly needs far more than +its role band, split ownership before merely raising the number. + +Common artifact types: + +```text +workflow_status +product_vision +workflow_atlas +source_pack_atlas +source_atlas +wave_charter +discovery_brief +initiative +initiative_roadmap +initiative_index +retained_note +sprint_plan +sprint_decision_log +sprint_closeout +evidence_index +source_pack_readme +research_claim_registry +workflow_reference +``` + +Historical captures may keep old artifact types as capture-time truth. Do not +rewrite raw historical evidence only to normalize metadata. + +## Source-Pack Readme Metadata + +Every source pack includes `00-readme.md` with the standard frontmatter fields +and: + +1. status; +2. date basis; +3. read triggers; +4. do-not-read triggers; +5. default section limit; +6. promotion rule; +7. last reviewed date when known. + +Source packs preserve retained context. They do not authorize delivery by +themselves. + +## Trace Tokens + +Trace-token lookup policy lives in `references/trace-tokens.md`. Trace tokens +are owner-only anchors for workflow lookup, not closeout summaries or metadata +payloads. + +## Context Receipt + +Include a receipt when context choice affects confidence. + +Required receipt triggers: + +1. discovery acceptance; +2. sprint preview or closeout; +3. final audit or wave transition; +4. retained context was opened; +5. the normal read budget was exceeded; +6. a broader writeback decision is being made. + +```text +Context receipt: +- Loaded: +- Skipped: +- Source-pack fanout: +- Budget exception: +``` + +Good receipts explain the route, not every incidental search result. For small +owner-only edits, do not create receipt boilerplate unless one of the triggers +applies. + +## Retained-Context Read Receipt + +Use this when source packs, retained notes, historical discoveries, or old +closeouts shape current work: + +```text +Retained-context read receipt: +- Trigger: +- Search: +- Opened: +- Promoted: +- Not promoted: +``` + +If retained context changes current direction, promote the changed fact into +the owner artifact before accepting the discovery or closeout. + +## Evidence Index Shape + +Sprint evidence belongs behind `evidence/index.md` unless a host deliberately +chooses a stricter evidence store. The index is a claim-to-proof router, not a +second closeout or a raw evidence dump: + +```text +State: + + +Validated Claims: +| Claim | Evidence | Gate | Status | Consumed By | +| --- | --- | --- | --- | --- | +| | | | | | + +Evidence Files: +| File | Type | Status | Open When | +| --- | --- | --- | --- | +| | | | | + +Live Gates And Deferred Evidence: + + +Redaction And Retention: + + +Promotion: + + +Read Policy: + +``` + +The evidence index is T4. It should be opened through a specific validation or +audit trigger, not as normal startup context. Material closeout claims must be +backed by the validated-claims table; unresolved or unavailable proof must be +recorded as blocked, deferred, not triggered, or out of scope. + +Generated runtime state under sprint evidence (any project-specific +scratch directory) is local scratch by default. Do not commit it unless the +sprint explicitly approves a no-secret export; commit redacted evidence files +and summarize scratch-state disposition in the evidence index instead. + +## Broader Writeback Decision + +Closeout must decide whether work changed broader owners: + +```text +Broader writeback: +- status.md: +- vision.md: +- wave.md: +- initiative roadmap/index: +- source packs: +``` + +Writebacks update owned facts by replacement. Do not append chronology just to +record that a sprint happened. + +## Live Validation Matrix + +Sprint previews and closeouts use a live validation matrix when external +systems, credentials, UI checks, provider behavior, or timing-sensitive claims +matter: + +```text +| Gate | Required? | Owner | Evidence path | Status | +| --- | --- | --- | --- | --- | +| | yes/no/conditional | agent/operator | | pending/passed/failed/deferred | +``` + +Missing credentials or operator action is `blocked pending operator action` +unless the operator explicitly postpones the live gate. + +## Research Claim Registries + +When discovery relies on outside research or retained source packs, keep claims +traceable: + +```text +| Claim | Source | Checked at | Confidence | Promoted to | +| --- | --- | --- | --- | --- | +| | | | high/medium/low | | +``` + +Do not preserve long quotes or raw captures in current owner artifacts. Keep +capture-time truth in source packs or evidence records. + +## Manual Checks + +Useful repository checks: + +```text +rg -n "Context receipt|Broader writeback|Retained-context read" .ub-workflows +rg -n "context_tier|summary_budget_lines" .ub-workflows +rg --files .ub-workflows/waves -g "**/sprints/**/evidence/index.md" +``` diff --git a/.agents/skills/ub-workflow/references/placeholder-contract.md b/.agents/skills/ub-workflow/references/placeholder-contract.md index 7fa2e6f..bebf148 100644 --- a/.agents/skills/ub-workflow/references/placeholder-contract.md +++ b/.agents/skills/ub-workflow/references/placeholder-contract.md @@ -1,71 +1,39 @@ # Placeholder Contract -This contract defines how `ub-workflow` treats unresolved placeholders in -generated initiative artifacts. +Default placeholder validation applies to generated workflow output only. -## Scope +Covered generated artifacts: -Default placeholder validation applies to generated initiative output only. +1. `vision.md` and `status.md` when generated by the helper; +2. `wave.md`; +3. `initiative.md`; +4. `roadmap.md`; +5. `index.md`; +6. `discoveries/*.md`; +7. `sprints/*/sprint.md`; +8. `sprints/*/decision-log.md`; +9. `sprints/*/closeout.md`; +10. `sprints/*/evidence/index.md`. -Covered artifact paths: +## Required Findings -1. `README.md` -2. `roadmap.md` -3. `prd.md` -4. `retained-note.md` -5. `sprints/*/sprint.md` -6. `sprints/*/closeout.md` +Strict mode fails on: -Default placeholder validation does not treat the canonical internal templates -under `assets/initiative-template/` or `assets/operations-root/` as failures. +1. any `REPLACE_*` token; +2. plain-language `Replace with ...` prompts in `roadmap.md`, discovery + briefs, `sprint.md`, or `evidence/index.md`; +3. malformed generated names that do not follow `wNN`, `iNN`, `dNN`, `sNN`, or + `YYYY-MM-DD` rules. -## Placeholder Classes +## Advisory Findings -### Required +Strict mode does not fail on: -Required unresolved placeholders block strict-mode success. - -Rules: - -1. Any `REPLACE_*` token in a generated artifact is required. -2. Any plain-language `Replace with ...` prompt in `roadmap.md` is required. -3. Any plain-language `Replace with ...` prompt in `sprints/*/sprint.md` is - required. - -### Advisory - -Advisory unresolved placeholders stay visible in reports but do not fail -strict mode. - -Rules: - -1. Plain-language `Replace with ...` prompts in `prd.md` are advisory because - PRD authoring can still be in progress. -2. Plain-language `Replace with ...` prompts in `sprints/*/closeout.md` are - advisory because closeout completion happens after execution, not before it. -3. `PENDING_HANDOFF:` markers in prepared sprint PRDs are advisory because they - are explicit carry-forward reminders, not machine placeholders. - -## Generated-Output Behavior - -The scaffold helper and standalone checker should: - -1. print deterministic placeholder summaries for generated initiative output -2. distinguish required versus advisory findings explicitly -3. support strict-mode failure when required findings remain -4. keep canonical internal templates outside the default validation scope +1. closeout prompts that are meant to be filled after execution; +2. retained-note prompts before final audit; +3. explicit `PENDING_HANDOFF:` markers. ## Intended Use -Use strict mode when you need a generated initiative artifact set to be ready -for the next workflow phase. - -Examples: - -1. `init-sprints --strict-placeholders` should fail if the generated sprint - shells still contain `REPLACE_*` machine placeholders. -2. `prepare-sprints --strict-placeholders` should pass when roadmap-derived - sprint PRDs are rendered and only advisory closeout or handoff prompts - remain. -3. `check_scaffold_placeholders.py --strict` should fail only on required - generated-output findings. +Use strict mode before declaring a generated artifact ready for the next +workflow phase. diff --git a/.agents/skills/ub-workflow/references/scaffold-helper.md b/.agents/skills/ub-workflow/references/scaffold-helper.md index a413d5d..fb6a3ec 100644 --- a/.agents/skills/ub-workflow/references/scaffold-helper.md +++ b/.agents/skills/ub-workflow/references/scaffold-helper.md @@ -1,139 +1,56 @@ # Scaffold Helper -Use the helper script when you want deterministic initiative operations instead -of a manual copy workflow. +Use `scripts/scaffold_workflow.py` for deterministic workflow scaffolding. -Prefer `uv run python ...` when `uv` is available or the host repository uses -`uv`. If `uv` is unavailable or the host has a different configured runner, -replace `uv run python` with that local Python runner, such as `python`. +Prefer `uv run python` when a host uses uv. Otherwise use the host's local +Python runner. ## Commands -1. `uv run python .agents/skills/ub-workflow/scripts/scaffold_initiative.py create --prd-source ` -2. `uv run python .agents/skills/ub-workflow/scripts/scaffold_initiative.py prepare-sprints ` -3. `uv run python .agents/skills/ub-workflow/scripts/scaffold_initiative.py init-sprints ` -4. `uv run python .agents/skills/ub-workflow/scripts/scaffold_initiative.py archive ` -5. `uv run python .agents/skills/ub-workflow/scripts/check_scaffold_placeholders.py ` - -## What It Does - -1. bootstraps `./.ub-workflows/` from the operations-root assets when needed -2. creates dated initiative roots under `./.ub-workflows/initiatives/` -3. copies a provided source PRD into the initiative root as `./prd.md` without rewriting it -4. renders the core placeholders into the initiative control files -5. backfills `rollup.md` into existing initiative roots when that workflow - memory surface is missing -6. prepares sprint PRDs from roadmap metadata when explicit sprint-pack - preparation is requested -7. initializes the full sprint set from roadmap path entries on demand -8. backfills additive sprint files such as `decision-log.md` from the - canonical template into existing sprint directories without overwriting - prepared sprint content -9. archives completed initiatives on explicit request only -10. synchronizes the initiative-index `README.md` after create and archive - actions - -The current helper does not, by itself, guarantee execution-ready sprint PRDs. -Sprint content preparation remains a separate workflow step that must be -completed before Sprint 01 or any later sprint begins. - -When `prepare-sprints` is used, the helper renders roadmap-derived sprint PRDs -with richer execution-slice prompts and leaves only named pending handoff -markers where prior closeout truth may still need to flow forward. - -The helper now also prints generated-output placeholder summaries after -`create`, `prepare-sprints`, and `init-sprints`. - -Those summaries do not mean the scaffold is broken. -For `create` and `create-spec`, treat the output first as phase-status guidance: -the scaffold can be valid for PRD authoring, PRD review, roadmap planning, or -spec authoring even while later-phase placeholders still exist. -Likewise, `prepare-sprints` and `init-sprints` only prepare the sprint set: -they do not start Sprint 01 or any later sprint by themselves. -Actual sprint execution begins only when the active sprint is explicitly -started. - -Use `--strict-placeholders` on `create`, `prepare-sprints`, or `init-sprints` -when required unresolved generated-output placeholders should fail the command. - -## Safe Rerun Behavior - -The helper is intentionally conservative. - -Rules: - -1. if the operations root does not exist, `create` bootstraps it automatically -2. if the initiative root already contains files, `create` exits with an error -3. if a sprint directory already exists but is missing core files such as - `sprint.md`, `closeout.md`, or `evidence/`, `init-sprints` exits with an - error -4. if a sprint directory already exists and only lacks additive sprint files - such as `decision-log.md`, the helper backfills those files from the - canonical template without overwriting existing prepared content -5. if an initiative root predates `rollup.md`, `prepare-sprints` and - `init-sprints` backfill it from the canonical template -6. `archive` refuses to move incomplete initiatives -7. use `--dry-run` when you want to inspect the resolved action before writing files - -## Recommended Usage - ```bash -uv run python .agents/skills/ub-workflow/scripts/scaffold_initiative.py create --prd-source ./tmp/todo/parser-performance-prd.md --owner "Platform Team" -uv run python .agents/skills/ub-workflow/scripts/scaffold_initiative.py prepare-sprints ./.ub-workflows/initiatives/2026-04-02-parser-performance -uv run python .agents/skills/ub-workflow/scripts/scaffold_initiative.py init-sprints ./.ub-workflows/initiatives/2026-04-02-parser-performance -uv run python .agents/skills/ub-workflow/scripts/scaffold_initiative.py archive ./.ub-workflows/initiatives/2026-04-02-parser-performance +uv run python .agents/skills/ub-workflow/scripts/scaffold_workflow.py bootstrap +uv run python .agents/skills/ub-workflow/scripts/scaffold_workflow.py create-wave w12 agent-loop-hardening +uv run python .agents/skills/ub-workflow/scripts/scaffold_workflow.py create-initiative .ub-workflows/waves/w12-agent-loop-hardening review-controls +uv run python .agents/skills/ub-workflow/scripts/scaffold_workflow.py create-discovery .ub-workflows/waves/w12-agent-loop-hardening/initiatives/i01-review-controls approval-path +uv run python .agents/skills/ub-workflow/scripts/scaffold_workflow.py create-source-pack .ub-workflows/waves/w12-agent-loop-hardening action-review-research +uv run python .agents/skills/ub-workflow/scripts/scaffold_workflow.py prepare-sprint .ub-workflows/waves/w12-agent-loop-hardening/initiatives/i01-review-controls approval-runtime +uv run python .agents/skills/ub-workflow/scripts/check_scaffold_placeholders.py .ub-workflows --strict ``` -Optional arguments: - -- `create --ops-root`: override the default operations root -- `create --initiative-name`: set a display name that differs from the slug -- `create --owner`: record the initial initiative owner -- `create --date`: override the date stamp used in generated paths -- `create --phase`: override the initial initiative phase text -- `create --gate-state`: override the initial workflow gate state -- `create --roadmap-status`: override the initial roadmap status string -- `create --next-action`: override the initial next-action value in - `README.md` -- `create --prd-source`: copy the source PRD into the initiative root as - `./prd.md` -- `create --prd-imported`: mark the PRD as already execution-ready after - copy/import -- `create --strict-placeholders`: fail if generated output still has required - unresolved placeholders after scaffold creation -- `prepare-sprints --strict-placeholders`: fail if required generated-output - placeholders remain after sprint preparation -- `init-sprints --strict-placeholders`: fail if required generated-output - placeholders remain after sprint initialization -- `--dry-run`: report the resolved action without writing files - -Placeholder validation: - -1. default scope is generated initiative output, not canonical internal - templates -2. `check_scaffold_placeholders.py --strict` fails only on required findings -3. `PENDING_HANDOFF:` markers and generated closeout prompts remain advisory -4. see `references/placeholder-contract.md` for the exact required-versus-advisory rules - -## Follow-On Adaptation - -After scaffolding: - -1. replace `./prd.md` with the real initiative PRD when it is not already copied yet -2. review or refine `./prd.md` until `prd_ready: pass` -3. generate the full `roadmap.md` in one pass from the PRD -4. approve the roadmap and record `roadmap_ready: pass` in the initiative `README.md` -5. ensure the roadmap lists every implementation sprint plus the final audit item -6. run `prepare-sprints` to render roadmap-derived sprint PRDs before any sprint begins -7. review the rendered execution slices so acceptance, verification, and - dependencies are explicit before implementation begins -8. treat a prepared or initialized sprint set as pre-execution state until the - active sprint is explicitly started -9. keep sprint-time decisions in each sprint `decision-log.md` and summarize - cross-sprint carry-forward in `rollup.md` -10. treat `research/` as supportive discovery and `exceptions/` as bounded - exception records instead of default note buckets -11. run `init-sprints` when you need directory-only materialization or - validation of the sprint set -12. use `archive` only after the roadmap checklist, retained note, rollup, - and initiative status are actually complete +## Behavior + +1. `bootstrap` creates the normalized operations root, creates + `SOURCE_ATLAS.md` with a one-time source-root scan when absent, and creates + or patches root `AGENTS.md` with a managed workflow-routing section. +2. `create-wave` creates `waves/wNN-slug/` with `wave.md`, `discoveries/`, + `initiatives/`, `source-packs/`, Outcome Signals, Forecast And Appetite, + and `.gitkeep` markers for empty canonical folders. +3. `create-initiative` creates `initiatives/iNN-slug/` under a wave with + `roadmap.md`, triggered T3 `index.md`, Outcome Signals, Forecast And + Appetite, Forecast Control, `discoveries/`, and `sprints/`. +4. `create-discovery` detects whether the owner is a wave or initiative and + creates the correct `wNN-dNN` or `wNN-iNN-dNN` file with explicit user or + operator evidence status plus Forecast Impact for sequence-changing work. +5. `create-source-pack` creates a dated source pack under the operations root + or a wave root. +6. `prepare-sprint` creates only the next sprint by default and includes the + required closeout `Outcome And Learning Review` section plus a fail-closed + Routing Preflight, Discovery Triage prompt, Product Increment Contribution + prompt, explicit user or operator evidence status, closeout Forecast Delta, + claim-to-proof `evidence/index.md` scaffold, decision-latency mini-retro + prompt, retro evidence check, and evidence `.gitignore` for generated + runtime scratch state. +7. `prepare-sprint --all` is the explicit bulk materialization path. +8. `archive-initiative` moves a completed initiative to wave-local `archive/`. +9. Helpers remove `.gitkeep` when a canonical folder receives real content and + restore it when a canonical folder becomes empty. +10. Bootstrap source scanning is intentionally one-time. Use explicit + source-atlas maintenance when package boundaries or test topology change. + +## Safety + +- Existing non-empty targets are not overwritten. +- Human-owned gates are not set automatically. +- The helper creates scaffold structure; it does not start sprint execution. +- Placeholder checks apply to generated workflow output, not internal + templates. diff --git a/.agents/skills/ub-workflow/references/trace-tokens.md b/.agents/skills/ub-workflow/references/trace-tokens.md new file mode 100644 index 0000000..4380627 --- /dev/null +++ b/.agents/skills/ub-workflow/references/trace-tokens.md @@ -0,0 +1,102 @@ +# Trace Tokens + +Use this reference when searching old workflow decisions, adding lookup +metadata, or deciding where trace identifiers belong. + +## Purpose + +Trace tokens are stable search anchors for routed workflow lookup. They are not +mini-closeouts, metadata blobs, or execution authorization. + +The forward lookup path is: + +1. start with `status.md` and `WORKFLOW_ATLAS.md`; +2. use `SOURCE_PACK_ATLAS.md` for retained research; +3. use `SOURCE_ATLAS.md` for source-code routing; +4. use the initiative `index.md` `Trace Routes` table for old workflow facts + through a triggered T3 lookup; +5. open discoveries, sprint packs, closeouts, decision logs, or evidence only + through a routed trigger. + +## Owner-Only Policy + +Trace tokens live only in routing owners: + +1. `status.md` when a trace is current posture; +2. `wave.md`; +3. `initiative.md`; +4. `roadmap.md`; +5. `index.md`; +6. `retained-note.md`; +7. source-pack `00-readme.md`; +8. workflow atlases when they route trace lookup. + +Do not add trace tokens to discoveries, sprint packs, decision logs, closeouts, +or evidence indexes. Those artifacts keep normal prose, decisions, validation +summaries, and evidence links. + +## Token Format + +Use compact trace tokens: + +```text +Trace token: `DH-W11-I01-S10-CLOSEOUT: bounded_action_review_runtime_proof_passed` +``` + +Rules: + +1. project prefix is optional; Dark Horse uses `DH-`; +2. IDs use wave, initiative when relevant, artifact number, and token kind; +3. the payload is one short `lower_snake_case` summary; +4. do not put semicolon `key=value` chains in the token payload; +5. put searchable facets in `tags` and `Trace Routes`, not the token line. + +Common token kinds: + +```text +PATH-A +PREVIEW +START +CLOSEOUT +VALIDATION +EVIDENCE +INVENTORY +TRANSITION +AUDIT +``` + +## Owner Metadata + +Routing owners may add frontmatter fields when trace lookup would benefit: + +```yaml +trace_ids : [DH-W11-I01-S10-CLOSEOUT] +tags : [agentloop, action-review, provider-live-smoke] +``` + +Use `lower-kebab-case` tags. Keep tags stable, few, and search-oriented. + +## Trace Routes + +Each initiative `index.md` should include a compact `Trace Routes` table: + +```markdown +## Trace Routes + +| Trace ID | Kind | Status | Tags | Owner | Evidence | Read Trigger | +| --- | --- | --- | --- | --- | --- | --- | +| `DH-W11-I01-S10-CLOSEOUT` | sprint closeout | passed | agentloop, action-review | `sprints/.../closeout.md` | `sprints/.../evidence/index.md` | reconstructing Sprint 10 result | +``` + +Keep one row per meaningful accepted discovery, completed sprint, audit, +transition, or durable retained decision. Do not duplicate closeout prose in +the table. + +## Cleanup Rule + +When normalizing older artifacts, remove dense token lines from non-owner +artifacts. If the token was the only place a material fact existed, preserve +that fact as nearby prose before removing the token. + +Do not create a separate trace atlas. Use existing atlases plus initiative +indexes. diff --git a/.agents/skills/ub-workflow/references/validation-and-completion.md b/.agents/skills/ub-workflow/references/validation-and-completion.md index 774efd1..0101b10 100644 --- a/.agents/skills/ub-workflow/references/validation-and-completion.md +++ b/.agents/skills/ub-workflow/references/validation-and-completion.md @@ -1,193 +1,149 @@ -# Validation and Completion - -Use this reference to decide when each initiative phase is complete enough to -move forward. - -## PRD Readiness - -`prd_ready` is `pass` only when: - -1. the problem is clearly defined -2. goals and non-goals are explicit -3. assumptions, constraints, and unknowns that shape the PRD are explicit -4. the chosen path is justified -5. at least one alternative was evaluated and rejected -6. success criteria are verifiable -7. dependencies and risks are explicit -8. validation expectations name concrete commands or checks where known -9. documentation touch points are explicit -10. governance bridge level is explicit when governance coordination is needed -11. another operator could continue without chat history - -## Lightweight Spec Readiness - -A lightweight spec is ready only when: - -1. the work is explicitly bounded and does not need a full roadmap and sprint - pack yet -2. the problem, goals, and non-goals are explicit -3. assumptions, constraints, and unknowns are explicit -4. the chosen path is justified -5. at least one alternative was evaluated and rejected -6. validation expectations are concrete instead of implied -7. documentation touch points are explicit when they matter -8. the boundary to direct bounded work and the promotion trigger to a full - initiative are explicit -9. if the spec was created by promotion, the reason direct bounded work was no - longer the smallest safe surface is explicit -10. the next action is explicit -11. another operator could continue without chat history -12. the active interaction mode is explicit when the spec will drive - user-facing or resumable execution behavior - -## Research Readiness - -`research_ready` is `pass` only when: - -1. the current problem or initiative context is grounded enough to support a - durable PRD -2. open questions that would block PRD authorship are either answered or - explicitly recorded -3. repository truth checks needed for PRD scope have been completed where known -4. another operator could understand why the initiative exists without relying - on chat history - -## Roadmap Readiness - -`roadmap_ready` is `pass` only when: - -1. the roadmap exists and is derived from the current `prd.md` -2. sprint ordering and dependencies are explicit -3. every planned sprint declares path, goal, validation focus, subtasks, and evidence folder -4. the final roadmap item is a final audit -5. the roadmap is rich enough to initialize sprint folders without relying on chat history -6. the agent has surfaced a review checklist covering sprint breakdown completeness, ordering and dependencies, scope boundaries and non-goals, and validation/docs expectations -7. the human explicitly approved the roadmap -8. `README.md` points to sprint initialization as the correct next step -9. repository-specific validation and documentation expectations are explicit where known -10. the initiative interaction mode is explicit in the initiative status - surfaces when the initiative will drive sprint execution +# Validation And Completion + +Use this reference for readiness, closeout, and completion checks. + +## Wave Readiness + +A wave is ready when: + +1. `wave.md` states outcome, why now, scope boundaries, success evidence, + outcome signals, Forecast And Appetite, initiative map, and transition or + reroute rules; +2. any activation discovery is accepted; +3. at least one initiative can be created without relying on chat history; +4. root options were reviewed for activation candidates; +5. source-pack routes are explicit when retained research is needed. + +## Initiative Readiness + +An initiative is ready for sprint planning when: + +1. `initiative.md` has outcome bet, appetite, success evidence, circuit + breaker, outcome signals, Forecast And Appetite, goals, non-goals, and + constraints; +2. `roadmap.md` has Forecast Control, an adaptive plan, active or next route, + and revalidation rules; +3. `index.md` exists as a triggered T3 durable lookup and history surface; +4. `options.md` exists for possible local insertions before closeout; +5. the active or next discovery is accepted or explicitly pending; +6. WIP state is compatible with the constrained dual-track policy. + +## Discovery Readiness + +A discovery is ready for decision when: + +1. repo truth is current enough for the question; +2. user or operator evidence status is `used`, `not triggered`, or `deferred` + with a reason and decision impact; +3. relevant source packs, standards, donor notes, or outside research are cited + or explicitly skipped; +4. options and recommendation are clear; +5. risks and stop conditions are explicit; +6. validation expectations are named; +7. roadmap-changing insertions, splits, reroutes, or deferrals have Forecast + Impact and have been promoted into the owning `roadmap.md`; +8. option promotions, demotions, or removals are reflected in root or + initiative-local `options.md` when relevant; +9. the decision slot is ready for operator acceptance, rejection, or redirect. ## Sprint Content Readiness `sprint_content_ready` is `pass` only when: -1. every planned sprint has a standalone `sprint.md` -2. every planned sprint has a `decision-log.md` available for running - sprint-level memory -3. the active or next sprint is execution-ready rather than a placeholder shell -4. the active or next sprint breaks work into reviewable execution slices -5. the active or next sprint makes acceptance and verification explicit for - those slices instead of leaving success implied -6. later sprints contain only named pending handoff markers that legitimately - depend on prior closeout truth -7. each sprint names concrete validation expectations and handoff guidance -8. the sprint pack is rich enough to survive a session reset without relying on - chat history - -## Sprint Initialization - -Do not start sprint execution until: - -1. the roadmap exists -2. `roadmap_ready` is `pass` -3. all planned sprint folders are initialized -4. `sprint_content_ready` is `pass` -5. each planned sprint has a standalone `sprint.md` -6. each planned sprint has a `decision-log.md` -7. each planned sprint includes a concrete validation plan -8. when needed, `sprint_start_ready` is explicit after context refresh -9. the final roadmap item is a final audit -10. the workflow stops after initialization and waits for an explicit user - request before the active sprint checkpoint begins +1. the sprint is pulled from accepted discovery or reviewed preview; +2. `sprint.md`, `decision-log.md`, `closeout.md`, and `evidence/index.md` + exist; +3. the sprint has one objective and execution-ready slices; +4. bet framing is present; +5. Product Increment Contribution is recorded as `direct`, `enabling`, or + `audit`; +6. enabling sprints name the visible increment they unblock and why a direct + slice is not viable; +7. two consecutive enabling or prerequisite sprints trigger a route review + with options, pros/cons, and an operator decision to ship a vertical proof, + cut/defer scope, reroute, or buy more enabling work; +8. validation and live gates are concrete, including which gates are required + objective proof versus optional, not-triggered, or out-of-scope checks; +9. user or operator evidence status is `used`, `not triggered`, or `deferred`; +10. Project Evolution Gate inventory exists when triggered; +11. operational surface preflight exists when the sprint introduces or changes + a repo-owned operational surface, including owner, lifecycle, visibility, + safety policy, validation path, and inventory or topology impact; +12. unclear operational-surface ownership, lifecycle, safety policy, + validation, or inventory impact that may change scope, architecture, risk, + or acceptance criteria has been promoted to discovery before execution; +13. options-board validation has passed when the sprint is pulled from an + option or changes the options route; +14. placeholders that block execution are resolved. ## Sprint Start Readiness `sprint_start_ready` is `pass` only when: -1. the active or next sprint is execution-ready -2. the smallest required resume file set has been read after any session reset -3. blockers or pending handoff markers have been resolved or explicitly carried - forward -4. the next action is explicit before implementation begins -5. the execution slices are reviewable enough that another operator could pick - a slice and start work without re-planning the sprint -6. the sprint `decision-log.md` exists and is ready to absorb running - decisions as execution proceeds -7. the active interaction mode is explicit and does not conflict with the - current initiative status artifacts -8. in `reviewed` mode, the pre-sprint preview is written down and explicitly - states that the sprint has not started yet -9. in `reviewed` mode, non-trivial sprint previews preserve the richer - counterfactual structure: - `What Repo Truth Says`, `Inference`, `Implementation Paths`, - `Recommendation`, then the questions that change the sprint path -10. in `reviewed` mode, any questions that change the sprint path are resolved, - and the later explicit human approval starts the sprint directly while being - recorded as `sprint_start_ready: pass` when that gate is used +1. current repo truth has been refreshed; +2. stale candidates have been revalidated; +3. WIP policy allows the sprint; +4. blockers are resolved or explicitly carried; +5. reviewed mode approval was given in a later message after preview when + reviewed mode is active. -## Archive Readiness +## Sprint Closeout -`archive_ready` is `pass` only when: +`sprint_closeout` is `pass` only when: -1. `initiative_complete` is effectively satisfied pending explicit human review -2. the final audit output is ready for review -3. `retained-note.md`, `README.md`, and `roadmap.md` reflect the final state -4. archive is being considered explicitly rather than as an automatic side - effect +1. every accepted exit criterion has fresh named passing evidence, or the + sprint remains active or blocked; +2. required validation and live gates pass after the final relevant change; +3. evidence is saved and routed through `evidence/index.md`, with required + objective proof separated from optional, not-triggered, blocked, + out-of-scope, or operator-deferred checks; +4. decision log is current; +5. outcome and learning review is recorded; +6. material closeout result, validation, and route-changing claims are backed + by `evidence/index.md`; required objective proof cannot be deferred while + the original objective closes as passed; +7. broader writeback decisions are recorded in the owning artifacts; +8. route-changing learning is promoted into `roadmap.md`; +9. durable lookup learning is compactly promoted into the triggered T3 `index.md`; +10. Forecast Delta is recorded, including planned versus actual, hidden + prerequisite discovered, remaining forecast impact, and owner updates; +11. sequence expansion beyond appetite records the operator decision after + scoped cut/defer, reroute, and buy-more tradeoffs were presented; +12. triggered Project Evolution Gate items are converted, removed, or explicitly + operator-deferred; +13. the mini-retro is recorded, including decision latency and retro evidence + check; +14. local options are promoted, moved, rejected, or removed when the sprint + changes initiative closeout posture; +15. next action is explicit. + +If required objective proof is missing, stale, failing, or only shows that a +non-objective smoke path ran, the sprint does not pass. Continue iterating +while the accepted objective remains reachable; otherwise mark the sprint +blocked or ask the operator to change scope, reroute, or buy more work. + +## Final Audit + +A final audit checks: + +1. roadmap scope was executed, parked, or explicitly deferred; +2. no material work was silently skipped; +3. bought, parked, cut, and deferred scope is explicit; +4. evidence and closeouts support claimed outcomes; +5. broad docs and route maps are current; +6. roadmaps and options boards do not hide required unfinished work; +7. initiative `index.md` supports lookup of meaningful discoveries, closeouts, + evidence, and supersession notes; +8. retained note is ready; +9. terminal-audit-mode options validation has no required findings; +10. archive readiness is surfaced for human review. -## Sprint Closeout +## Archive Readiness -`sprint_closeout` is `pass` only when: +Archive only after explicit request and when: -1. planned in-scope work is complete or explicitly blocked -2. known in-scope defects are documented -3. validation results are recorded -4. relevant documentation and synchronized artifacts are updated or explicitly marked unchanged -5. evidence pointers exist when evidence was generated -6. touched workflow documents satisfy ub-quality formatting and structure rules -7. the active sprint `decision-log.md` reflects the material sprint decisions, - reversals, or deferrals -8. `rollup.md` is updated or explicitly left unchanged when the sprint did not - materially affect cross-sprint understanding -9. the next sprint can resume from `closeout.md`, `decision-log.md`, and - `roadmap.md` -10. the workflow's next-step behavior matches the active interaction mode -11. when the active interaction mode surfaces user-facing post-execution - reporting, considerations moving forward and things to watch are explicit -12. when the active interaction mode surfaces post-execution reporting, a - recoverable post-execution summary is recorded in `closeout.md` -13. in `reviewed` mode, the post-execution report itself is the pause boundary - before any later move-on request opens the next pre-sprint preview - -## Initiative Completion - -`initiative_complete` is `pass` only when: - -1. all implementation sprints have closeout records -2. the final audit ran as the last roadmap item -3. initiative-level validation is recorded and traceable -4. relevant documentation and synchronized artifacts reflect the shipped behavior -5. follow-up audit or refactor decisions were captured -6. `retained-note.md` was written -7. `rollup.md`, `README.md`, and `roadmap.md` reflect the final state -8. touched workflow documents satisfy ub-quality formatting and structure rules -9. the final audit output is ready for human review before any archive action -10. the recorded interaction mode history does not contradict the final - initiative state - -## Review Questions - -When validating an initiative or sprint, ask: - -1. could another developer, PM, or agent resume this without prior chat - history? -2. is the next action explicit? -3. is the current blocker or gate state explicit? -4. was the scale decision intentional: direct bounded task, lightweight spec, - or initiative? -5. if lane promotion happened, is the reason for that promotion explicit? -6. are validation expectations concrete instead of implied? -7. are documentation and synchronized artifacts accounted for instead of assumed? -8. do the touched workflow documents satisfy ub-quality formatting and structure rules? -9. is the final audit still present as the terminal roadmap step? +1. final audit passed; +2. retained note exists; +3. initiative roadmap, index, and status reflect completion; +4. initiative-local options are resolved; +5. `status.md` no longer points at the initiative as active. diff --git a/.agents/skills/ub-workflow/references/workflow-contract.md b/.agents/skills/ub-workflow/references/workflow-contract.md index 91a6b3f..21869ad 100644 --- a/.agents/skills/ub-workflow/references/workflow-contract.md +++ b/.agents/skills/ub-workflow/references/workflow-contract.md @@ -1,485 +1,359 @@ # Workflow Contract -Use this contract for initiatives that need planning, decomposition, stop-resume -safety, and a durable completion record. - -## Intake Classification - -Start rough work by choosing the smallest lane that can still hold the needed -decisions and validation. - -1. direct bounded task: use when the work is a truly small fix or bounded task - with straightforward execution and no need for a durable planning artifact -2. lightweight spec: use when the work is still bounded, but now needs - assumptions, scope, options, validation, or an execution shape written down - without justifying a roadmap and sprint pack -3. initiative: use when the work is multi-session, risky, cross-cutting, - staged, or likely to benefit from a PRD, roadmap, and resumable sprint - execution model - -The lifecycle below applies to initiative work. Lightweight specs are a -bounded alternative path, not a weakened initiative lane. - -## Lane Promotion Heuristics +Use this reference for the detailed product-agile workflow contract. -Use these heuristics to keep direct bounded work narrow without making lane -selection mechanical. +## Operating Model -Stay in direct bounded work when: - -1. the task is a truly small bounded fix -2. execution is straightforward enough that a durable artifact would add more - ceremony than clarity -3. another operator could still execute the work safely from the live context - without reconstructing assumptions, options, or validation - -Promote to a lightweight spec when: - -1. brainstorming has become real planning, even before implementation starts -2. the work now needs explicit goals, non-goals, assumptions, alternatives, or - validation written down -3. the agent is forming a concrete execution plan that should survive chat - loss, handoff, or pause -4. the work has multiple moving parts but still does not need roadmap-driven - sequencing or sprint preparation - -Common triggers: - -1. planning-heavy conversation -2. multiple meaningful options -3. likely cross-file or cross-surface coordination -4. explicit execution plan formation -5. repeated clarifications that are shaping the contract of the work -6. likely multi-session continuation - -Promote to an initiative when: - -1. the work now needs PRD-level decomposition -2. sequencing or dependencies matter enough to need a roadmap -3. execution likely spans sessions or contributors -4. the change is clearly cross-cutting enough that sprint preparation would - reduce risk - -Bias: - -1. prefer a lightweight spec over an initiative for medium planning work -2. escalate to an initiative earlier once staged execution is clearly emerging - -Promotion visibility: - -1. keep lane choice lightweight for true small direct work -2. when promoting from direct bounded work to a lightweight spec or from a - lightweight spec to an initiative, surface a short promotion note -3. that note should name the new lane, explain why the prior lane is no longer - the smallest safe surface, and explain why the chosen lane is sufficient - without over-escalating - -## Lifecycle - -Execute work through these phases: - -1. research and discovery -2. PRD authoring and readiness -3. initiative scaffold and baseline setup -4. roadmap generation and approval -5. sprint-content preparation -6. sprint materialization and start readiness -7. ordered sprint execution -8. sprint closeout and review pause -9. final audit and review pause -10. retained note and archive decision - -## Initiative-Level Gates - -Use these workflow gates: - -| Gate | Meaning | Allowed States | Ownership | -| ---------------------- | --------------------------------------------------------------- | ------------------------- | ----------------------------- | -| `research_ready` | Discovery is grounded enough to support a durable PRD | `pass`, `fail`, `blocked` | shared workflow gate | -| `prd_ready` | The PRD is execution-ready and roadmap work can start | `pass`, `fail`, `blocked` | shared workflow gate | -| `roadmap_ready` | The roadmap is execution-ready and approved for downstream work | `pass`, `fail`, `blocked` | human-owned review checkpoint | -| `sprint_content_ready` | The sprint pack has execution-ready sprint PRDs | `pass`, `fail`, `blocked` | shared workflow gate | -| `sprint_start_ready` | The next sprint can begin after context refresh when needed | `pass`, `fail`, `blocked` | optional shared start gate | -| `sprint_closeout` | The active sprint is safe to pause, hand off, or close | `pass`, `fail`, `blocked` | shared workflow gate | -| `archive_ready` | Final audit output is ready for explicit archive review | `pass`, `fail`, `blocked` | human-owned review checkpoint | -| `initiative_complete` | The initiative has completed final audit and retained note | `pass`, `fail`, `blocked` | shared terminal workflow gate | - -State intent: - -- `pass`: required workflow controls are satisfied -- `fail`: the work was evaluated and one or more controls failed -- `blocked`: the workflow cannot progress yet because prerequisites are missing - -Ownership intent: - -- `human-owned review checkpoint`: requires explicit user approval or review - before the workflow advances -- `shared workflow gate`: can be evaluated by the operator or agent, but the - rationale must be written down in initiative artifacts -- `optional shared start gate`: use when a fresh or resumed sprint needs an - explicit start-readiness confirmation before execution begins - -## Interaction Modes - -Interaction mode is a workflow-behavior layer, not a readiness layer. - -Lane decides which artifacts and readiness checks are required. -Mode decides how execution is surfaced to the user once that lane is actually -ready. - -Mode precedence: - -1. explicit user turn override -2. persisted artifact mode -3. default fallback = `reviewed` - -Persistence: - -1. initiative lane: persist mode in initiative artifacts -2. lightweight-spec lane: persist mode in `spec.md` -3. direct bounded lane: runtime only unless the work is promoted into a - durable artifact - -Canonical modes: - -1. `reviewed` - - user-facing pre-sprint preview as a distinct sprint-start checkpoint - - the preview evaluates what the sprint would do if it started now, before - any implementation begins - - non-trivial sprints should surface multiple implementation paths with - concise pros and cons plus a recommended path - - questions that change the sprint path should be resolved before execution - using the structured question fallback when needed - - explicit human approval before execution; when `sprint_start_ready` is - used, that gate records the same approval rather than adding another - prompt - - user-facing post-execution reporting - - the post-execution report is the pause boundary between sprints or - bounded execution chunks - - a later move-on request opens the next pre-sprint preview and start - approval prompt -2. `flow` - - short user-facing pre-execution note - - richer user-facing post-execution reporting - - no pre-execution pause, but manual advancement after each sprint or - bounded execution chunk -3. `auto` - - internal pre-execution analysis by default - - concise user-facing post-execution reporting - - automatic advancement unless interruption conditions are met -4. `continuous` - - user-facing alias: `yolo` - - internal analysis and artifact updates still required - - no routine user-facing pre/post-execution reporting - - no routine pause between sprints or bounded execution chunks - - interrupt only when a major blocker or conflict requires aborting or - pausing the work - -Question handling: - -1. for multiple-choice user prompts, follow the shared choice-question - contract in `../ub-authoring/references/authoring-conventions.md` -2. when text questions are used for a reviewed-mode pre-sprint preview, keep - the same decision structure as the canonical reviewed-mode pre-sprint - preview pattern below. -3. In `reviewed` mode, resolve the questions that change the sprint path - before the explicit start-approval question. - A request like `Start the next sprint.` opens the preview, but it does not - count as sprint-start approval in the same turn. - A later affirmative approval after that preview starts execution directly - and records `sprint_start_ready: pass` when the gate is used. - -Mode reporting: - -1. user-facing execution contexts should include a concise mode reference so - the user does not need to search the docs for the mode names -2. in `reviewed` mode, the pre-sprint preview should explicitly say the sprint - has not started yet and should explain what the sprint would do if it - started now -3. for non-trivial reviewed-mode sprints, that preview should surface at least - two plausible implementation paths with concise pros and cons plus a - recommended path -4. in `reviewed` mode, the preview should make the active sprint, chosen path, - approval boundary, and any questions that change the sprint path explicit - before execution begins -5. for non-trivial reviewed-mode sprints, lead the user-facing preview with - the actual sprint analysis rather than artifact-update or validation - bookkeeping; artifact sync notes are secondary and should not be the opener -6. user-facing post-execution reporting should cover what changed, why it - mattered, considerations moving forward, assumptions made, and things to - watch whenever the active mode surfaces post-execution reporting -7. in `reviewed` mode, the post-sprint report is the pause; the next user - move-on request opens pre-sprint analysis for the next sprint and asks for - approval to start it - -## Reviewed-Mode Pre-Sprint Preview Pattern - -This is the canonical reviewed-mode sprint-start pattern. -Other workflow surfaces should summarize it, not redefine it. - -Always required: - -1. state that the sprint is still in pre-sprint mode -2. state that no implementation has started yet -3. explain what the sprint would do if it started now -4. name the intended or recommended path -5. state the approval boundary explicitly -6. state that execution begins only after a later approval message, not from - the same start request that opened the preview -7. state that the later approval starts the sprint directly and is not followed - by a second start prompt - -Required only for non-trivial reviewed-mode sprints: - -1. lead with the actual sprint analysis, not artifact-update or validation - bookkeeping -2. include a `What Repo Truth Says` section that captures the current repo - facts that materially shape the sprint -3. include an `Inference` section that explains what those facts mean for the - sprint now -4. include an `Implementation Paths` section with at least two plausible paths -5. include concise pros and cons for each path -6. mark the recommended path with `(*)` -7. include a `Recommendation` section that explains why the recommended path - is currently the best fit -8. ask the questions that change the sprint path before asking for the single - explicit sprint-start approval -9. close with the explicit approval boundary and a no-edits-yet statement - -Treat a sprint as non-trivial when any of these are true: - -1. more than one plausible path would materially change scope, ordering, - touched surfaces, or later sprints -2. the sprint touches shared contracts, governance boundaries, or other - cross-cutting behavior -3. the user could reasonably want to steer the path before execution starts - -Compact example: +The portable hierarchy is: ```text -Sprint 03 is still in pre-sprint mode only. -No implementation has started. - -If we started this sprint now, the job would be to tighten governance-owned -guidance around the minimum durable record without changing the governance -model. - -What Repo Truth Says - -- The governance model is already coherent enough for normal initiative work. -- The remaining friction is that “minimum durable record” is still slower to - infer than it should be. -- The repo does not need a new governance system; it needs faster operator - guidance. - -Inference - -This sprint should stay narrow and calibrate governance-owned guidance rather -than widen into command-policy cleanup or catalog-wide consistency work. - -Implementation Paths - -`A` (*) narrow owner-surface calibration -(Best fit because it solves the fast-path problem directly without widening -scope.) -`B` broader governance-surface harmonization -(Pros: more complete in one pass. Cons: blends into later consistency work.) -`Custom` - -Recommendation - -`A` is the strongest fit because it improves the operator fast path without -quietly redesigning governance. - -Questions That Change The Sprint Path - -Which path should this sprint use before it starts? +Product Vision -> Product Options -> Outcome Waves -> Initiatives -> Discoveries -> Sprints +``` -Start approval: -I have not started Sprint 03. -This preview turn does not start execution. -Execution would begin only after a later approval message that approves -path `A`. That approval would start the sprint directly; there will not be a +The model is not a full Scrum, SAFe, Shape Up, or Kanban implementation. It +keeps the useful controls from each while optimizing for AI-assisted work, +context recovery, evidence, and adaptive delivery. + +## Artifact Owners + +- Root `AGENTS.md` owns repo-local agent instructions and a small managed + workflow-routing section. +- Root `SOURCE_ATLAS.md` owns source-code routing, initial source scan output, + local source boundaries, and source-route maintenance rules. +- `vision.md` owns the adaptable product north star. +- Root `options.md` owns curated product-level, future-wave, and unknown-owner + options before commitment. It is not a backlog ledger, completion history, + or execution authorization surface. +- `status.md` owns current product posture, wave sequencing, active pointers, + WIP state, blockers, candidate tracks, retained-context routes, and next + allowed action. +- `waves/wNN-*/wave.md` owns wave-level vision: outcome, why now, scope + boundaries, bet framing, non-goals, success evidence, outcome signals, + initiative map, retained inputs, and transition or reroute rules. +- Wave `discoveries/wNN-dNN-*.md` owns activation, transition, or reroute + research. +- `initiatives/iNN-*/initiative.md` owns the initiative bet, outcome signals, + scope, durable decisions, and compact index pointers. +- `initiatives/iNN-*/options.md` owns possible initiative-local insertions + before closeout. Product-level or later-wave options move to root + `options.md`. +- `initiatives/iNN-*/roadmap.md` owns the adaptive strategy map, active or + next sprint route, candidate sequence, insertion points, and revalidation + rules. +- `initiatives/iNN-*/index.md` owns triggered compact lookup, durable history, + meaningful artifacts, evidence routes, and supersession notes. +- Initiative `discoveries/wNN-iNN-dNN-*.md` owns initiative/sprint-shaping + research. +- Sprint `sprint.md` owns execution-ready scope, slices, validation, and start + checkpoint. +- Sprint `decision-log.md` owns sprint-time decisions and reversals. +- Sprint `closeout.md` owns result, evidence summary, outcome and learning + review, mini-retro, and handoff. +- Sprint `evidence/index.md` owns evidence routing, validated claim mapping, + gate status, redaction posture, promotion targets, and read policy. +- Root or wave `source-packs/YYYY-MM-DD-*/` own retained research and doctrine. + +## Options Validation And Transition Rituals + +Run options validation whenever work crosses a commitment boundary: + +1. wave activation; +2. initiative activation or closeout; +3. option promotion into roadmap or discovery; +4. terminal audit; +5. sprint preview pulled from an option. + +Before wave activation, review root `options.md`, relevant source-pack +readmes, and unresolved local options from the closing initiative. Promote, +park, merge, or reject options before creating the activation discovery. + +Before initiative closeout, run closeout-mode options validation. Every local +option must be promoted to roadmap, moved to root options, rejected, or +removed as obsolete before closeout can pass. + +Before terminal audit, run terminal-audit-mode options validation. The audit +must prove that roadmaps and options boards do not hide required unfinished +work. + +Before sprint preview from an option, revalidate the option against current +repo truth. Use discovery when route, scope, contract, validation, runtime +boundary, or appetite may change. Use reviewed preview only when the route is +already decided and the preview is just freshness and approval-boundary work. + +Structural workflow changes that affect artifact ownership, lifecycle gates, +scaffold output, transition policy, or recovery context require a compact +workflow-improvement discovery or equivalent accepted decision record. + +## WIP Policy + +Default WIP is constrained dual-track: + +1. one active delivery sprint per active initiative; +2. one active discovery per active initiative; +3. one wave-level discovery only during activation, transition, or reroute; +4. options boards are pre-commitment memory, not delivery commitments or + execution queues; +5. no sprint execution from a stale option or candidate entry. + +If a repository chooses more WIP, the active status artifact must record the +reason, owner, and stop condition. + +## Discovery And Delivery + +Discovery is upstream of delivery, but not an endless phase gate. + +A sprint may start only when one of these is true: + +1. it is pulled from an accepted discovery; +2. a reviewed sprint preview proves the current candidate is still valid; +3. the work is a small direct bounded task and does not need workflow artifacts. + +Use discovery when the route needs a decision. Discovery is required when +current evidence may change sequence, scope, appetite, product direction, +contract shape, runtime boundary, or the recommended path; when path-shaping +questions are unresolved; when previous closeout learning changes the route; +when standards, best practices, official docs, current primary research, +analogous-system evidence, source-pack, user, or operator evidence is needed +to choose between approaches; or when a preview cannot honestly prove that the +registered candidate is still the right next slice. + +Before a reviewed sprint preview claims discovery is unnecessary, run +Discovery Triage as a fail-closed Routing Preflight. Record the trigger +categories considered before choosing preview. Trigger categories include +autonomy, authority, runtime-boundary, policy, evidence, interoperability, +agent-behavior changes, agent loops, harnesses, loop continuation, goal +judgment, budgets, and checkpoints. Record one of these outcomes: + +1. `preview_ok`: the route is already decided and the preview can revalidate + freshness, scope, risks, validation, and the approval boundary because any + triggered evidence cannot change route, contract, scope, validation, + runtime boundary, or implementation path; +2. `discovery_required`: external evidence or path selection may change the + route, contract, scope, validation, runtime boundary, or implementation + path; +3. `operator_decision_needed`: the blocking choice is product appetite, + scope, or priority rather than research alone; +4. `not_triggered`: outside evidence was considered and is not relevant, with + a concrete reason. + +For autonomy, authority, runtime-boundary, policy, evidence, +interoperability, or agent-behavior changes, outside evidence is presumed +relevant unless triage records a concrete reason why it is not. Agent loops, +harnesses, loop continuation, goal judgment, budgets, and checkpoints are +portable trigger examples, not a requirement that all sprints run discovery. +Portable outside evidence includes industry standards, best practices, +official docs, current primary research, analogous systems, and relevant source +packs. Repository overlays may add project-specific evidence sources and +triggers. + +Use a reviewed sprint preview when the route is already registered and the +task is to revalidate freshness, scope, risks, validation, and the approval +boundary before start. If preview work uncovers route-changing uncertainty, +stop the preview and promote the question to discovery before implementation. + +Discovery must record current repo truth, user or operator evidence status, +relevant standards or research, relevant source-pack or analogous-system +comparison when useful, options, recommendation, risks, validation +expectations, and a user decision slot. + +Discovery acceptance is incomplete when the discovery changes future sequence +but the owning `roadmap.md` still lacks that insertion, split, reroute, or +deferral, including Forecast Impact and the operator decision that accepted +the tradeoff or bought more scope. Sprint closeout is incomplete when it +changes the next route but the owning `roadmap.md` is not updated. Durable +lookup facts are promoted into `index.md` through a triggered lookup writeback. + +When the previous sprint's learning affects a new route decision, the next +discovery reads the latest closeout and promotes only the routing-relevant +facts. It does not duplicate the whole closeout review. + +## Outcome Signals + +Waves and initiatives record qualitative Outcome Signals: + +1. product or user signal: what user, operator, customer, or product-value + evidence should move; +2. delivery or flow signal: what should improve about batch size, cycle time, + WIP, blocked time, or route clarity; +3. quality or stability signal: what should improve about correctness, + reliability, validation, live behavior, or failure handling; +4. context or evidence cost signal: what should stay cheap enough for agents + and operators to recover, verify, and continue the work. + +Outcome Signals are lightweight routing signals. They do not create a separate +metrics ledger, recurring report, or hard numeric KPI unless a repository +explicitly adopts one. + +Discoveries and sprint previews record User Or Operator Evidence with one of +three statuses: `used`, `not triggered`, or `deferred`. Purely internal +technical work may use `not triggered`, but the artifact must say why that +evidence did not affect the current decision. + +## Appetite-Boxed Forecast Calibration + +Appetite-Boxed is the default forecast-control rule. Candidate counts are +forecasts, not commitments, and sequence expansion is not automatic +adaptation. When discovery or closeout finds pressure to add work, the agent +must state the pressure, propose options with tradeoffs, and ask for an +explicit operator decision to cut/defer scope, reframe, reroute, or buy more. +Appetite pressure does not justify silent under-delivery: if the accepted +objective remains reachable by continued iteration, continue; if the objective +must change, ask the operator to cut scope, reroute, block, or buy more work. + +Wave and initiative owner docs record Forecast And Appetite: + +1. appetite; +2. forecast range or count; +3. confidence; +4. throughput basis; +5. known unknowns; +6. scope hammers: operator-choice options that could cut, defer, or reframe + scope; +7. expansion trigger: what requires operator decision. + +`roadmap.md` records Forecast Control: completed count, registered remaining, +forecast delta, appetite state, and next scope tradeoff. Appetite states are +`within_appetite`, `at_risk`, `exceeded_pending_decision`, or +`operator_bought_expansion`. + +Discoveries and reviewed previews record Forecast Impact when they change +sequence. The allowed results are `fits appetite`, `cuts/defers scope`, +`requires operator buy-more`, or `reroutes/stops`. + +Sprint previews record Product Increment Contribution as `direct`, +`enabling`, or `audit`. Enabling sprints must name the visible product +increment they unblock and why a direct slice is not viable. + +Two consecutive enabling or prerequisite sprints trigger a route review asking +whether to ship a vertical proof, cut/defer scope, reroute, or explicitly buy +more enabling work. The agent recommends; the operator decides. Major +capability candidates must decompose prerequisite risks and the first usable +product increment before acceptance. + +## Bet Framing + +Every initiative and non-trivial sprint records: + +1. `appetite`: how much effort/risk is worth spending before re-evaluation; +2. `success evidence`: what proof makes the bet worth keeping; +3. `circuit breaker`: what stops or reroutes the work; +4. `non-goals`: what must not sneak into the bet; +5. `deferral path`: where useful not-now work will live. + +Bet framing is not a second governance system. It prevents roadmap candidates +and options boards from becoming invisible backlog commitments. + +## Reviewed-Mode Preview + +In reviewed mode, a move-on request opens a preview only. The preview states: + +1. the sprint has not started; +2. what would happen if it started now; +3. the recommended path; +4. questions that change path, if any; +5. the exact approval boundary. + +Non-trivial previews use this order: + +1. `What Repo Truth Says` +2. `Inference` +3. `Discovery Triage` +4. `Why Preview Instead Of Discovery` +5. `User Or Operator Evidence` +6. `Forecast Impact` when sequence changes +7. `Product Increment Contribution` +8. `Implementation Paths` +9. `Recommendation` +10. `Questions That Change The Sprint Path` +11. `Approval Boundary` + +A later explicit approval starts the sprint directly and does not trigger a second start prompt. -No files were edited in this pre-sprint evaluation step. -``` +## Candidate Queues -## Execution Rules - -1. Finish or explicitly defer the discovery needed to make the PRD - self-contained before advancing `prd_ready: pass`. -2. Make the scale decision explicit before opening initiative artifacts: - direct bounded task, lightweight spec, or initiative. -3. Keep direct bounded work narrow; do not stay direct once the conversation - becomes planning-heavy, medium-sized, execution-shaped, or clearly useful - enough that another operator would benefit from a durable mini-contract. -4. Do not route rough ideas into a full initiative when a direct bounded task - or lightweight spec is sufficient. -5. Use a lightweight spec under `./.ub-workflows/specs/YYYY-MM-DD-slug/spec.md` - when the work is still bounded but now needs assumptions, scope, options, - validation, or an execution plan written down. -6. Planning-heavy brainstorming is enough to justify a lightweight spec when it - has become real execution shaping rather than casual chat. -7. Prefer a lightweight spec over an initiative for medium planning work, but - escalate to an initiative as soon as the work clearly needs PRD-level - decomposition, roadmap sequencing, or staged execution. -8. When lane promotion happens, surface a short promotion note that explains - why the prior lane is no longer the smallest safe surface. -9. Treat `roadmap.md` as the durable post-plan artifact. -10. Generate the full roadmap in one pass. -11. Surface the roadmap review checklist and wait for explicit human approval - before setting `roadmap_ready: pass`. -12. Do not prepare sprint content, initialize sprint folders, or begin sprint - execution until `roadmap_ready: pass`. -13. Prepare each planned sprint as a standalone execution-ready `sprint.md` - before Sprint 01 or any later sprint begins. -14. During sprint preparation, expand roadmap subtasks into richer execution - slices in the sprint plan rather than leaving the sprint as a flat checklist. -15. Use named pending handoff markers only in sprint fields that legitimately - depend on prior closeout truth. -16. Materialize or repair sprint folders only after roadmap approval and in a - way that preserves the prepared sprint content. -17. When a fresh or resumed sprint needs additional context refresh, record that - checkpoint explicitly before advancing `sprint_start_ready: pass`. -18. In `reviewed` mode, surface a distinct pre-sprint preview checkpoint before - execution begins. -19. That preview must make explicit that no implementation has started yet, - explain what the sprint would do if started now, surface alternatives when - the sprint is non-trivial, and ask any questions that change the sprint - path needed to calibrate the sprint path. -20. For non-trivial reviewed-mode sprints, that preview should lead with the - sprint analysis itself: - `What Repo Truth Says`, `Inference`, `Implementation Paths`, - `Recommendation`, then the questions that change the sprint path. - Do not lead the user-facing preview with artifact-update or validation - bookkeeping. -21. Wait for explicit human approval only after the reviewed-mode preview and - its questions are resolved, then start the sprint and record - `sprint_start_ready: pass` when that gate is used. -22. In `reviewed` mode, that approval must come in a later user reply after - the preview is shown. - Do not infer sprint-start approval from the same user turn that requested - the sprint start. - Do not ask a second start question after that later approval. -23. Stop after sprint-pack preparation and wait for an explicit user request - before Sprint 01 or any later sprint begins. -24. Keep sprint execution ordered unless the roadmap explicitly allows parallel - work. -25. Resolve and honor the active interaction mode before execution begins. -26. For initiative sprint execution, every mode requires the same readiness - prerequisites: approved roadmap, prepared sprint pack, execution-ready - current sprint, and no unresolved blockers preventing safe execution. -27. Use each sprint's `decision-log.md` as the running sprint-level memory - surface and use `rollup.md` as the readable initiative-level carry-forward - summary. -28. Keep `research/` supportive and cross-sprint in character, and keep - `exceptions/` bounded and explicit instead of treating either folder as a - generic note dump. -29. Update `roadmap.md`, the initiative `README.md`, and `rollup.md` whenever - state changes materially affect later resume work. -30. Keep the active sprint's `decision-log.md` and `closeout.md` current before - pausing. -31. When the active mode surfaces post-execution reporting, write a recoverable - post-execution summary into `closeout.md` before the workflow pauses or - advances. - In `reviewed` mode, treat that report itself as the pause boundary. -32. Materialize newly introduced additive workflow files in existing sprint - folders from the canonical `ub-workflow` sprint template when it evolves, - without overwriting prepared sprint content. -33. `reviewed` and `flow` stop after every sprint closeout so the human can - review before the next sprint begins. -34. `auto` may continue after sprint closeout unless a hard blocker, material - ambiguity, repo-truth conflict, or later-sprint-shaping decision requires - interruption. -35. `continuous` / `yolo` may continue without routine user-facing reporting, - but must abort or pause when a major blocker or conflict requires explicit - user resolution, and that interruption must be documented clearly. -36. End the roadmap with a final audit step, then stop for explicit review - before `archive_ready: pass` or any archive action. -37. Treat the number of implementation sprints as PRD-driven; the roadmap can - contain `Sprint 01` through `Sprint NN` before the final audit. - -## Operations Root Bootstrap - -For this repository, the deterministic helper owns operations-root bootstrap. +Candidate queues are not backlogs. Rules: -1. If `./.ub-workflows/` is missing, `create` bootstraps it before creating the initiative. -2. The generated operations root does not require a copied local `initiative-template/` directory. -3. The helper must keep the operations-root `README.md` synchronized after create and archive actions. +1. candidates are hypotheses, not execution authorization; +2. candidate counts are forecasts, not commitments; +3. stale candidates revalidate on touch; +4. candidate states are `required`, `probable`, `conditional`, + `adaptive insertion`, `parked`, or `terminal audit`; +5. a final audit candidate stays visible until initiative completion; +6. a pre-audit continuation window must exist before final audit; +7. expansion beyond appetite requires operator choice after the agent presents + cut/defer, reroute, and buy-more tradeoffs. + +The roadmap owns candidate order and sequence-change rationale. The index owns +lookup and durable history. Do not duplicate sprint token ledgers in the +roadmap. + +## Sprint Outcome And Learning Review + +Sprint closeout records: + +1. what the sprint achieved; +2. how the project is better after the sprint; +3. what could have been done better; +4. whether the learning changes the next route, stays local, or suggests a + workflow improvement. + +Route-changing learning must be promoted into `roadmap.md` before closeout +passes. Durable lookup learning must be compactly promoted into the triggered +T3 `index.md`. +Every material achievement, project-improvement, validation, or route-changing +claim in the closeout must be backed by `evidence/index.md`. Required +objective proof cannot be recorded as deferred while the original sprint +objective closes as passed; missing or failing required proof keeps the sprint +active or blocked until it passes or the operator explicitly changes scope. + +Sprint closeout also records Forecast Delta: planned versus actual, hidden +prerequisite discovered, remaining forecast impact, and whether `roadmap.md`, +`index.md`, or `status.md` were updated. + +## Objective-Complete Sprint Completion + +Choose an objective-complete action: implement and validate all work required +for the accepted sprint objective and exit criteria. Avoid unrelated expansion, +but do not cut, defer, or split required proof just to preserve scope or +budget. + +Scope-control words like `smallest`, `narrow`, and `only as needed` mean the +smallest objective-complete vertical slice. They do not authorize stopping at +the first green focused test, skipping a named repo-owned surface, or omitting +required evidence. If the smallest objective-complete slice no longer fits the +accepted sprint, ask the operator to cut scope, reroute, block, or buy more. + +A sprint closes as passed only when every required objective gate has fresh +named passing evidence after the final relevant change. Smoke tests, +orientation scans, or partial deterministic proof cannot stand in for a +required live or end-to-end gate named by the sprint. + +## Closeout Mini-Retro + +Sprint closeout records: + +1. process friction; +2. evidence cost; +3. context cost; +4. decision latency; +5. workflow adjustment, or `none`; +6. retro evidence check: objective signal, controllability, and whether the + friction repeated from prior work; +7. whether the adjustment is local or should be promoted to this skill after + repeated evidence. ## Recovery Rules -When the initiative state is partial or inconsistent, prefer the smallest corrective step: - -1. rough idea without a clear lane: make the scale decision before opening PRD - or roadmap work -2. missing `./.ub-workflows/`: run the deterministic create flow and bootstrap - it -3. initiative exists without a copied or refined `./prd.md`: import or - complete the PRD before planning continues -4. initiative exists without a finished roadmap: complete `roadmap.md` before - preparing sprint content or initializing sprints -5. roadmap exists but is not yet approved: keep sprint preparation and sprint - initialization blocked and finish roadmap review first -6. roadmap exists without prepared sprint content: prepare the sprint pack - before execution continues -7. sprint folders exist but the active or next `sprint.md` is still a - placeholder shell: block execution and complete sprint preparation first -8. later sprint start depends on prior closeout truth: read the prior - `closeout.md` and replace any named pending handoff markers that are now - resolvable -9. initiative or sprint memory surfaces are missing after template evolution: - backfill `rollup.md` or sprint `decision-log.md` from the canonical - templates before continuing -10. archive requested before completion: block the archive and explain the - missing controls - -## Resume Order - -When resuming inside one initiative root, read in this order: - -1. `./roadmap.md` -2. `./rollup.md` when it exists -3. the most relevant prior sprint `closeout.md` when one exists -4. the active or next sprint `sprint.md` -5. the active sprint `decision-log.md` when one exists and the sprint is in - progress -6. `./README.md` -7. `./prd.md` only if initiative-level context is still missing - -When resuming a lightweight spec root, read `./spec.md` first. - -## Stop-Resume Discipline - -Before stopping work, ensure: - -1. `README.md` reflects the current phase and next action -2. `roadmap.md` reflects current status and the next action -3. the active or next sprint has an execution-ready `sprint.md` before any - sprint start, or the active sprint has an up-to-date `closeout.md` when - execution has already begun -4. `rollup.md` reflects any cross-sprint decision, validation, or deferral - changes that materially affect later work -5. the active sprint's `decision-log.md` is current enough to explain the - running state -6. any generated evidence is stored with the active sprint -7. blockers are written down explicitly -8. the human review checkpoint is explicit whenever sprint-pack preparation, - sprint closeout, or final audit just completed - -## Final Audit Minimum - -The final audit must confirm at minimum: - -1. roadmap scope was actually executed -2. no material work was silently skipped -3. synchronized docs, tests, and related artifacts are current where applicable -4. required validation has been run or explicitly deferred -5. the user was asked about follow-up audits or refactors -6. the retained note reflects the final state -7. `rollup.md` reflects the final cross-sprint summary -8. archive readiness was surfaced explicitly for human review before any - archive action +Prefer objective-complete correction: + +1. missing operations root: bootstrap it; +2. missing wave: create the wave before initiative work; +3. missing initiative: create it under the owning wave; +4. missing discovery: create or accept discovery before delivery pulls work; +5. stale candidate: run fresh discovery or reviewed preview; +6. placeholder sprint: prepare the active or next sprint before start; +7. missing evidence index: backfill it before closeout; +8. oversized status or wave files: move detail to owner artifacts. diff --git a/.agents/skills/ub-workflow/scripts/check_scaffold_placeholders.py b/.agents/skills/ub-workflow/scripts/check_scaffold_placeholders.py index 1d213e8..90e8ff0 100644 --- a/.agents/skills/ub-workflow/scripts/check_scaffold_placeholders.py +++ b/.agents/skills/ub-workflow/scripts/check_scaffold_placeholders.py @@ -1,8 +1,6 @@ #!/usr/bin/env python3 """Check generated workflow artifacts for unresolved scaffold placeholders.""" -from __future__ import annotations - import argparse import importlib.util import json @@ -10,11 +8,11 @@ import sys SCRIPT_DIR = Path(__file__).resolve().parent -SCAFFOLD_SCRIPT = SCRIPT_DIR / "scaffold_initiative.py" +SCAFFOLD_SCRIPT = SCRIPT_DIR / "scaffold_workflow.py" def load_scaffold_module(): - spec = importlib.util.spec_from_file_location("ub_workflow_scaffold_initiative", SCAFFOLD_SCRIPT) + spec = importlib.util.spec_from_file_location("ub_workflow_scaffold", SCAFFOLD_SCRIPT) if spec is None or spec.loader is None: raise ImportError(f"Unable to load scaffold helper from {SCAFFOLD_SCRIPT.as_posix()}") module = importlib.util.module_from_spec(spec) @@ -31,7 +29,6 @@ def build_payload(scan_root: Path) -> dict[str, object]: payload_roots: list[dict[str, object]] = [] required_count = 0 advisory_count = 0 - for workflow_root in workflow_roots: findings = SCAFFOLD_MODULE.collect_placeholder_findings(workflow_root) root_required = sum(1 for finding in findings if finding.severity == "required") @@ -46,7 +43,9 @@ def build_payload(scan_root: Path) -> dict[str, object]: "summary": SCAFFOLD_MODULE.format_placeholder_summary(workflow_root, findings), "findings": [ { - "file": finding.file_path.resolve().relative_to(workflow_root.resolve()).as_posix(), + "file": finding.file_path.resolve() + .relative_to(workflow_root.resolve()) + .as_posix(), "line": finding.line_number, "category": finding.category, "severity": finding.severity, @@ -57,10 +56,8 @@ def build_payload(scan_root: Path) -> dict[str, object]: ], } ) - - status = "fail" if required_count else "pass" return { - "status": status, + "status": "fail" if required_count else "pass", "scanRoot": scan_root.resolve().as_posix(), "rootCount": len(workflow_roots), "requiredCount": required_count, @@ -69,51 +66,23 @@ def build_payload(scan_root: Path) -> dict[str, object]: } -def print_text_report(payload: dict[str, object]) -> None: - roots = payload.get("roots") - if not isinstance(roots, list): - raise ValueError("Payload roots must be a list") - if not roots: - print("placeholder summary: no workflow roots were found in scope") - return - for index, root_payload in enumerate(roots): - if index: - print() - print(root_payload["summary"]) - - def main() -> int: parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument( - "scan_root", - nargs="?", - default=str(Path(".ub-workflows")), - help="Workflow root, initiatives directory, specs directory, .ub-workflows root, or repo root to scan", - ) - parser.add_argument( - "--strict", - action="store_true", - help="Exit non-zero when required unresolved placeholders are present", - ) - parser.add_argument( - "--format", - choices=("text", "json"), - default="text", - help="Output format", - ) + parser.add_argument("scan_root", nargs="?", default=str(Path(".ub-workflows"))) + parser.add_argument("--strict", action="store_true") + parser.add_argument("--format", choices=("text", "json"), default="text") args = parser.parse_args() - - scan_root = Path(args.scan_root).resolve() - payload = build_payload(scan_root) - + payload = build_payload(Path(args.scan_root).resolve()) if args.format == "json": print(json.dumps(payload, indent=2)) else: - print_text_report(payload) - - if args.strict and payload["requiredCount"]: - return 1 - return 0 + roots = payload.get("roots") + if isinstance(roots, list): + for index, root_payload in enumerate(roots): + if index: + print() + print(root_payload["summary"]) + return 1 if args.strict and payload["requiredCount"] else 0 if __name__ == "__main__": diff --git a/.agents/skills/ub-workflow/scripts/check_workflow_options.py b/.agents/skills/ub-workflow/scripts/check_workflow_options.py new file mode 100644 index 0000000..659ebb5 --- /dev/null +++ b/.agents/skills/ub-workflow/scripts/check_workflow_options.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +"""Check workflow options boards for lifecycle drift.""" + +import argparse +from datetime import datetime, timezone +import importlib.util +import json +from pathlib import Path +import sys + +SCRIPT_DIR = Path(__file__).resolve().parent +SCAFFOLD_SCRIPT = SCRIPT_DIR / "scaffold_workflow.py" + + +def load_scaffold_module(): + spec = importlib.util.spec_from_file_location("ub_workflow_scaffold", SCAFFOLD_SCRIPT) + if spec is None or spec.loader is None: + raise ImportError(f"Unable to load scaffold helper from {SCAFFOLD_SCRIPT.as_posix()}") + module = importlib.util.module_from_spec(spec) + sys.modules.setdefault(spec.name, module) + spec.loader.exec_module(module) + return module + + +SCAFFOLD_MODULE = load_scaffold_module() + + +def finding_payload(finding) -> dict[str, object]: + try: + file_name = finding.file_path.resolve().relative_to(finding.workflow_root.resolve()) + except ValueError: + file_name = finding.file_path.resolve() + return { + "file" : file_name.as_posix(), + "line" : finding.line_number, + "category" : finding.category, + "severity" : finding.severity, + "message" : finding.message, + } + + +def build_payload( + scan_root: Path, + *, + mode: str, + stale_days: int, + include_history: bool, +) -> dict[str, object]: + workflow_root = SCAFFOLD_MODULE.discover_workflow_root(scan_root) + findings = SCAFFOLD_MODULE.collect_workflow_options_findings( + workflow_root, + mode=mode, + stale_days=stale_days, + include_history=include_history, + today=datetime.now(tz=timezone.utc).date(), + ) + required_count = sum(1 for finding in findings if finding.severity == "required") + advisory_count = len(findings) - required_count + return { + "status" : "fail" if required_count else "pass", + "scanRoot" : scan_root.resolve().as_posix(), + "workflowRoot" : workflow_root.as_posix(), + "mode" : mode, + "staleDays" : stale_days, + "includeHistory": include_history, + "requiredCount" : required_count, + "advisoryCount" : advisory_count, + "summary" : SCAFFOLD_MODULE.format_options_summary(workflow_root, findings), + "findings" : [finding_payload(finding) for finding in findings], + } + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("scan_root", nargs="?", default=str(Path(".ub-workflows"))) + parser.add_argument("--strict", action="store_true") + parser.add_argument( + "--mode", + choices=("normal", "closeout", "transition", "terminal-audit"), + default="normal", + ) + parser.add_argument("--stale-days", type=int, default=45) + parser.add_argument("--include-history", action="store_true") + parser.add_argument("--format", choices=("text", "json"), default="text") + args = parser.parse_args() + + payload = build_payload( + Path(args.scan_root).resolve(), + mode=args.mode, + stale_days=args.stale_days, + include_history=args.include_history, + ) + if args.format == "json": + print(json.dumps(payload, indent=2)) + else: + print(payload["summary"]) + return 1 if args.strict and payload["requiredCount"] else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/.agents/skills/ub-workflow/scripts/scaffold_initiative.py b/.agents/skills/ub-workflow/scripts/scaffold_initiative.py deleted file mode 100644 index ed18f9b..0000000 --- a/.agents/skills/ub-workflow/scripts/scaffold_initiative.py +++ /dev/null @@ -1,1660 +0,0 @@ -#!/usr/bin/env python3 -"""Manage the repository initiative workflow under ./.ub-workflows.""" - -from __future__ import annotations - -import argparse -from collections.abc import Mapping, Sequence -from dataclasses import dataclass -from datetime import datetime, timezone -from pathlib import Path -import re -import shutil - -# region Constants - -SKILL_ROOT = Path(__file__).resolve().parents[1] -DEFAULT_INITIATIVE_TEMPLATE_ROOT = SKILL_ROOT / "assets" / "initiative-template" -CANONICAL_SPRINT_TEMPLATE_ROOT = DEFAULT_INITIATIVE_TEMPLATE_ROOT / "sprint-template" -DEFAULT_OPERATIONS_TEMPLATE_ROOT = SKILL_ROOT / "assets" / "operations-root" -DEFAULT_SPEC_TEMPLATE_ROOT = SKILL_ROOT / "assets" / "lightweight-spec-template" -DEFAULT_OPS_ROOT = Path(".ub-workflows") -TEXT_FILE_SUFFIXES = { - ".md", - ".txt", - ".yaml", - ".yml", - ".json", -} -KNOWN_COMMANDS = {"create", "create-spec", "prepare-sprints", "init-sprints", "archive"} -ACTIVE_INITIATIVE_HEADING = "## Active Initiative Roots" -ACTIVE_SPEC_HEADING = "## Active Lightweight Specs" -OPERATIONS_INDEX_FILES = {"AGENTS.md", "README.md", "operation-guide.md"} -SPRINT_ENTRY_PATTERN = re.compile(r"^-\s+\[[ xX]\]\s+(.+?)\s*$") -SPRINT_SUBTASK_PATTERN = re.compile(r"^\s+-\s+\[[ xX]\]\s+(.+?)\s*$") -SPRINT_PATH_PATTERN = re.compile(r"^\s+-\s+Path:\s+`?(.+?sprint\.md)`?\s*$") -SPRINT_GOAL_PATTERN = re.compile(r"^\s+-\s+Goal:\s+(.+?)\s*$") -SPRINT_DEPENDS_PATTERN = re.compile(r"^\s+-\s+Depends on:\s+(.+?)\s*$") -SPRINT_VALIDATION_PATTERN = re.compile(r"^\s+-\s+Validation focus:\s+(.+?)\s*$") -SPRINT_EVIDENCE_PATTERN = re.compile(r"^\s+-\s+Evidence folder:\s+`?(.+?)`?\s*$") -PENDING_HANDOFF_PREFIX = "PENDING_HANDOFF:" -LEGACY_SPRINT_INIT_UNCHECKED = "- [ ] All sprint folders initialized under `./sprints/` from `./sprint-template/`" -LEGACY_SPRINT_INIT_CHECKED = "- [x] All sprint folders initialized under `./sprints/` from `./sprint-template/`" -SPRINT_INIT_UNCHECKED = ( - "- [ ] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template" -) -SPRINT_INIT_CHECKED = ( - "- [x] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template" -) - -# endregion Constants - - -@dataclass(frozen=True) -class RoadmapSprintEntry: - """Structured sprint metadata extracted from roadmap.md.""" - - title: str - sprint_root: Path - sprint_file: Path - goal: str - depends_on: str - validation_focus: str - evidence_folder: str - subtasks: tuple[str, ...] - - -@dataclass(frozen=True) -class PlaceholderFinding: - """One unresolved generated-artifact placeholder finding.""" - - initiative_root: Path - file_path: Path - line_number: int - category: str - severity: str - marker: str - line_text: str - - -# region Path And Text Helpers - -MACHINE_PLACEHOLDER_PATTERN = re.compile(r"\bREPLACE_[A-Z0-9_]+\b") -HUMAN_PLACEHOLDER_PATTERN = re.compile(r"Replace with\b") -HUMAN_PLACEHOLDER_PROMPT_PATTERN = re.compile(r"^\s*(?:[-*+]\s+|\d+\.\s+)?(?:\[[ xX]\]\s+)?Replace with\b") -CODE_FENCE_PATTERN = re.compile(r"^\s*(```|~~~)") - - -def generated_artifact_role(initiative_root: Path, path: Path) -> str | None: - """Classify one generated workflow artifact path.""" - - try: - relative = path.resolve().relative_to(initiative_root.resolve()) - except ValueError: - return None - - if relative == Path("README.md"): - return "readme" - if relative == Path("roadmap.md"): - return "roadmap" - if relative == Path("spec.md"): - return "lightweight-spec" - if relative == Path("prd.md"): - return "prd" - if relative == Path("rollup.md"): - return "rollup" - if relative == Path("retained-note.md"): - return "retained-note" - if len(relative.parts) == 3 and relative.parts[0] == "sprints" and relative.parts[2] == "sprint.md": - return "sprint" - if len(relative.parts) == 3 and relative.parts[0] == "sprints" and relative.parts[2] == "decision-log.md": - return "decision-log" - if len(relative.parts) == 3 and relative.parts[0] == "sprints" and relative.parts[2] == "closeout.md": - return "closeout" - return None - - -def generated_artifact_paths(initiative_root: Path) -> list[Path]: - """Return the generated workflow artifacts covered by placeholder checks.""" - - spec_path = initiative_root / "spec.md" - if spec_path.exists() and spec_path.is_file(): - return [spec_path] - - candidates = [ - initiative_root / "README.md", - initiative_root / "roadmap.md", - initiative_root / "prd.md", - initiative_root / "rollup.md", - initiative_root / "retained-note.md", - ] - sprints_root = initiative_root / "sprints" - if sprints_root.exists(): - for sprint_root in sorted(path for path in sprints_root.iterdir() if path.is_dir()): - candidates.append(sprint_root / "sprint.md") - candidates.append(sprint_root / "decision-log.md") - candidates.append(sprint_root / "closeout.md") - return [path for path in candidates if path.exists() and path.is_file()] - - -def human_placeholder_is_required(initiative_root: Path, path: Path) -> bool: - """Return True when a plain-language placeholder blocks this generated artifact.""" - - return generated_artifact_role(initiative_root, path) in {"roadmap", "sprint", "lightweight-spec"} - - -def required_placeholder_markers(text: str, path: Path, initiative_root: Path) -> tuple[str, ...]: - """Return required placeholder markers for one generated artifact.""" - - markers = list(dict.fromkeys(MACHINE_PLACEHOLDER_PATTERN.findall(text))) - if human_placeholder_is_required(initiative_root, path) and HUMAN_PLACEHOLDER_PATTERN.search(text): - markers.append("Replace with") - return tuple(markers) - - -def collect_placeholder_findings(initiative_root: Path) -> list[PlaceholderFinding]: - """Collect required and advisory placeholder findings for one initiative root.""" - - findings: list[PlaceholderFinding] = [] - for path in generated_artifact_paths(initiative_root): - text = path.read_text(encoding="utf-8") - is_required_human_prompt = human_placeholder_is_required(initiative_root, path) - in_code_fence = False - for line_number, line in enumerate(text.splitlines(), start=1): - if CODE_FENCE_PATTERN.match(line): - in_code_fence = not in_code_fence - continue - if in_code_fence: - continue - findings.extend( - PlaceholderFinding( - initiative_root=initiative_root, - file_path=path, - line_number=line_number, - category="machine-token", - severity="required", - marker=marker, - line_text=line.strip(), - ) - for marker in MACHINE_PLACEHOLDER_PATTERN.findall(line) - ) - if HUMAN_PLACEHOLDER_PROMPT_PATTERN.search(line): - findings.append( - PlaceholderFinding( - initiative_root=initiative_root, - file_path=path, - line_number=line_number, - category="human-prompt", - severity=("required" if is_required_human_prompt else "advisory"), - marker="Replace with", - line_text=line.strip(), - ) - ) - if PENDING_HANDOFF_PREFIX in line: - findings.append( - PlaceholderFinding( - initiative_root=initiative_root, - file_path=path, - line_number=line_number, - category="pending-handoff", - severity="advisory", - marker=PENDING_HANDOFF_PREFIX, - line_text=line.strip(), - ) - ) - return findings - - -def format_placeholder_summary(initiative_root: Path, findings: Sequence[PlaceholderFinding]) -> str: - """Return a deterministic text summary for generated-output placeholder findings.""" - - required_count = sum(1 for finding in findings if finding.severity == "required") - advisory_count = len(findings) - required_count - if not findings: - return f"placeholder summary: no unresolved generated-artifact placeholders under {initiative_root.as_posix()}" - - lines = [ - ( - "placeholder summary: " - f"{required_count} required, {advisory_count} advisory finding(s) under {initiative_root.as_posix()}" - ) - ] - for finding in findings: - relative = finding.file_path.resolve().relative_to(initiative_root.resolve()).as_posix() - lines.append( - f"- {finding.severity} {finding.category}: {relative}:{finding.line_number} -> {finding.marker}" - ) - return "\n".join(lines) - - -def report_generated_placeholder_state(initiative_root: Path, *, strict: bool) -> None: - """Print generated-output placeholder findings and optionally fail on required ones.""" - - findings = collect_placeholder_findings(initiative_root) - summary = format_placeholder_summary(initiative_root, findings) - print(summary) - if strict and any(finding.severity == "required" for finding in findings): - raise ValueError( - "Generated workflow output still contains required unresolved placeholders:\n" - f"{summary}" - ) - - -def format_initiative_phase_status(args: argparse.Namespace, prd_source: Path | None) -> str: - """Describe the current-phase validity of a newly scaffolded initiative.""" - - if args.prd_imported: - return ( - "phase status: scaffold is valid for roadmap planning. " - "It is not yet ready for sprint preparation or initialization until " - "the roadmap is reviewed and `roadmap_ready: pass` is recorded." - ) - if prd_source is not None: - return ( - "phase status: scaffold is valid for PRD review and refinement. " - "It is not yet ready for sprint preparation or initialization until " - "`./prd.md` is execution-ready, `roadmap.md` is approved, and " - "`roadmap_ready: pass` is recorded." - ) - return ( - "phase status: scaffold is valid for PRD authoring. " - "It is not yet ready for sprint preparation or initialization until " - "the real `./prd.md` exists, `roadmap.md` is approved, and " - "`roadmap_ready: pass` is recorded." - ) - - -def format_spec_phase_status() -> str: - """Describe the current-phase validity of a newly scaffolded lightweight spec.""" - - return ( - "phase status: scaffold is valid for spec authoring. " - "It is not yet ready for direct execution or promotion until the " - "placeholders are replaced and the next action is explicit." - ) - - -def generated_roots_in_directory(root: Path) -> list[Path]: - """Return sorted generated workflow roots inside one container directory.""" - - if not root.exists() or not root.is_dir(): - return [] - return sorted(path for path in root.iterdir() if path.is_dir()) - - -def discover_generated_roots_for_placeholder_scan(scan_root: Path) -> list[Path]: - """Resolve one or more generated workflow roots from a scan target.""" - - resolved = scan_root.resolve() - if (resolved / "spec.md").exists(): - return [resolved] - if (resolved / "README.md").exists() and (resolved / "roadmap.md").exists(): - return [resolved] - if resolved.name == "initiatives" and resolved.is_dir(): - return generated_roots_in_directory(resolved) - if resolved.name == "specs" and resolved.is_dir(): - return generated_roots_in_directory(resolved) - if resolved.name == ".ub-workflows" and resolved.is_dir(): - return sorted( - [ - *generated_roots_in_directory(resolved / "initiatives"), - *generated_roots_in_directory(resolved / "specs"), - ] - ) - if (resolved / ".ub-workflows").is_dir(): - return discover_generated_roots_for_placeholder_scan(resolved / ".ub-workflows") - raise ValueError( - "Placeholder scan target must be a workflow root, an initiatives directory, " - "a specs directory, a .ub-workflows root, or a repository root containing " - "./.ub-workflows/initiatives/ or ./.ub-workflows/specs/." - ) - - -def discover_initiative_roots_for_placeholder_scan(scan_root: Path) -> list[Path]: - """Backward-compatible alias for generated workflow root discovery.""" - - return discover_generated_roots_for_placeholder_scan(scan_root) - -def derive_initiative_name(target_root: Path) -> str: - """Derive a readable initiative name from a dated or plain directory name.""" - - parts = [part for part in target_root.name.split("-") if part] - if len(parts) >= 4 and all(part.isdigit() for part in parts[:3]): - parts = parts[3:] - if not parts: - return target_root.name - return " ".join(parts).replace("_", " ").title() - - -def normalize_path(value: Path) -> str: - """Return a stable slash-based path string for generated files.""" - - current_root = Path.cwd().resolve() - try: - return value.resolve().relative_to(current_root).as_posix() - except ValueError: - return value.resolve().as_posix() - - -def slugify(value: str) -> str: - """Convert freeform text into a stable initiative slug.""" - - slug = re.sub(r"[^a-z0-9]+", "-", value.strip().lower()) - slug = slug.strip("-") - return slug or "initiative" - - -def dated_directory_name(raw_value: str, stamp: str) -> str: - """Return a dated initiative directory name from a slug or dated slug.""" - - candidate = raw_value.strip() - if re.fullmatch(r"\d{4}-\d{2}-\d{2}-.+", candidate): - return slugify(candidate[:10]) + "-" + slugify(candidate[11:]) - return f"{stamp}-{slugify(candidate)}" - - -def slug_source_name(source_path: Path) -> str: - """Return a slug basis derived from a source PRD filename.""" - - return source_path.stem - - -def strip_wrapping_backticks(value: str) -> str: - """Return a field value without surrounding Markdown code ticks.""" - - stripped = value.strip() - if stripped.startswith("`") and stripped.endswith("`") and len(stripped) >= 2: - return stripped[1:-1].strip() - return stripped - - -def replace_markdown_section(text: str, heading: str, body: str) -> str: - """Replace or append a Markdown section body under a heading.""" - - pattern = re.compile(rf"(?ms)^({re.escape(heading)}\n\n)(.*?)(?=^##\s|\Z)") - if pattern.search(text): - return pattern.sub(lambda match: f"{match.group(1)}{body}\n\n", text) - suffix = "" if text.endswith("\n") else "\n" - return f"{text}{suffix}\n{heading}\n\n{body}\n" - - -def update_markdown_table_value(text: str, field: str, value: str) -> str: - """Update a single Markdown table or bullet-list status row by field name.""" - - lines = text.splitlines() - updated_lines: list[str] = [] - for line in lines: - match = re.match(r"^\|\s*(.+?)\s*\|\s*(.+?)\s*\|$", line) - if match and match.group(1).strip() == field: - updated_lines.append(f"| {field:<21} | {value} |") - continue - bullet_match = re.match(r"^-\s+(.+?):\s+(.+?)\s*$", line) - if bullet_match and bullet_match.group(1).strip() == field: - updated_lines.append(f"- {field}: {value}") - continue - updated_lines.append(line) - return "\n".join(updated_lines) + ("\n" if text.endswith("\n") else "") - - -def read_markdown_table_value(text: str, field: str) -> str | None: - """Return a Markdown table or bullet-list value by field name when present.""" - - for line in text.splitlines(): - match = re.match(r"^\|\s*(.+?)\s*\|\s*(.+?)\s*\|$", line) - if match and match.group(1).strip() == field: - return match.group(2).strip() - bullet_match = re.match(r"^-\s+(.+?):\s+(.+?)\s*$", line) - if bullet_match and bullet_match.group(1).strip() == field: - return bullet_match.group(2).strip() - return None - - -def should_render(path: Path) -> bool: - """Restrict rendering to known text artifacts in the scaffold.""" - - return path.suffix in TEXT_FILE_SUFFIXES or path.name == "AGENTS.md" - - -def render_placeholders(root: Path, replacements: Mapping[str, str]) -> None: - """Render placeholders in copied text files while preserving unknown tokens.""" - - for path in sorted(root.rglob("*")): - if not path.is_file() or not should_render(path): - continue - text = path.read_text(encoding="utf-8") - updated = text - for placeholder, value in replacements.items(): - updated = updated.replace(placeholder, value) - if updated != text: - path.write_text(updated, encoding="utf-8") - - -def render_text_placeholders(text: str, replacements: Mapping[str, str]) -> str: - """Render a placeholder map against an in-memory template string.""" - - updated = text - for placeholder, value in replacements.items(): - updated = updated.replace(placeholder, value) - return updated - - -def find_blocking_placeholders(text: str) -> tuple[str, ...]: - """Return placeholder markers that still block execution readiness.""" - - markers: list[str] = [] - markers.extend(dict.fromkeys(MACHINE_PLACEHOLDER_PATTERN.findall(text))) - if HUMAN_PLACEHOLDER_PATTERN.search(text): - markers.append("Replace with") - return tuple(markers) - - -def find_pending_handoff_markers(text: str) -> tuple[str, ...]: - """Return allowed pending handoff markers from generated sprint text.""" - - return tuple( - line.strip() - for line in text.splitlines() - if PENDING_HANDOFF_PREFIX in line - ) - - -def sprint_document_has_blocking_placeholders(path: Path) -> bool: - """Return True when a sprint document still contains blocking placeholders.""" - - initiative_root = path.parents[2] - text = path.read_text(encoding="utf-8") - return bool(required_placeholder_markers(text, path, initiative_root)) - -# endregion Path And Text Helpers - - -# region Filesystem Helpers - -def ensure_directory_is_safe(target_root: Path) -> None: - """Reject writes against populated directories to avoid clobbering work.""" - - if not target_root.exists(): - return - if not target_root.is_dir(): - raise ValueError(f"Target path exists and is not a directory: {target_root.as_posix()}") - if any(target_root.iterdir()): - raise ValueError( - "Target directory already contains files. " - "Choose a new target or move the existing initiative first: " - f"{target_root.as_posix()}" - ) - - -def copy_tree(source: Path, destination: Path) -> None: - """Copy a template tree into the destination directory.""" - - shutil.copytree(source, destination, dirs_exist_ok=destination.exists()) - - -def copy_initiative_template(source: Path, destination: Path) -> None: - """Copy initiative control files while keeping sprint seeding internal.""" - - destination.mkdir(parents=True, exist_ok=True) - for child in sorted(source.iterdir()): - if child.name == "sprint-template": - continue - target = destination / child.name - if child.is_dir(): - copy_tree(child, target) - continue - shutil.copy2(child, target) - - -def determine_target_root(args: argparse.Namespace) -> Path: - """Resolve the new initiative root from a slug or explicit path.""" - - if args.target: - raw_target = args.target.strip() - candidate = Path(raw_target) - if candidate.is_absolute() or len(candidate.parts) > 1 or raw_target.startswith("."): - return candidate.resolve() - directory_name = dated_directory_name(raw_target, args.date) - return (Path(args.ops_root).resolve() / "initiatives" / directory_name).resolve() - - if not args.initiative_name: - if not args.prd_source: - raise ValueError("Provide either a target slug/path, --initiative-name, or --prd-source.") - directory_name = dated_directory_name(slug_source_name(Path(args.prd_source)), args.date) - return (Path(args.ops_root).resolve() / "initiatives" / directory_name).resolve() - directory_name = dated_directory_name(args.initiative_name, args.date) - return (Path(args.ops_root).resolve() / "initiatives" / directory_name).resolve() - - -def determine_spec_target_root(args: argparse.Namespace) -> Path: - """Resolve the new lightweight spec root from a slug or explicit path.""" - - if args.target: - raw_target = args.target.strip() - candidate = Path(raw_target) - if candidate.is_absolute() or len(candidate.parts) > 1 or raw_target.startswith("."): - return candidate.resolve() - directory_name = dated_directory_name(raw_target, args.date) - return (Path(args.ops_root).resolve() / "specs" / directory_name).resolve() - - if not args.spec_name: - raise ValueError("Provide either a target slug/path or --spec-name.") - directory_name = dated_directory_name(args.spec_name, args.date) - return (Path(args.ops_root).resolve() / "specs" / directory_name).resolve() - - -def build_active_root_list(ops_root: Path, root_name: str) -> str: - """Return one numbered active-root list for the operations root README.""" - - active_root = ops_root / root_name - active_items = sorted( - path.name for path in active_root.iterdir() if path.is_dir() - ) if active_root.exists() else [] - if not active_items: - return "1. `none`" - return "\n".join( - f"{index}. `{root_name}/{name}`" - for index, name in enumerate(active_items, start=1) - ) - - -def sync_ops_root_readme(ops_root: Path, template_root: Path) -> None: - """Synchronize the active workflow listings in the operations root README.""" - - readme_path = ops_root / "initiatives" / "README.md" - template_path = template_root / "README.md" - active_initiatives = build_active_root_list(ops_root, "initiatives") - active_specs = build_active_root_list(ops_root, "specs") - if readme_path.exists(): - text = readme_path.read_text(encoding="utf-8") - else: - text = template_path.read_text(encoding="utf-8") - updated = text.replace("REPLACE_ACTIVE_INITIATIVE_ROOTS", active_initiatives) - updated = text.replace("REPLACE_ACTIVE_LIGHTWEIGHT_SPECS", active_specs) - updated = replace_markdown_section(updated, ACTIVE_INITIATIVE_HEADING, active_initiatives) - updated = replace_markdown_section(updated, ACTIVE_SPEC_HEADING, active_specs) - readme_path.write_text(updated, encoding="utf-8") - - -def ensure_operations_root( - ops_root: Path, - operations_template_root: Path, - initiative_template_root: Path, -) -> None: - """Bootstrap the repository operations root when it is missing or partial.""" - - ops_root.mkdir(parents=True, exist_ok=True) - initiatives_root = ops_root / "initiatives" - initiatives_root.mkdir(parents=True, exist_ok=True) - specs_root = ops_root / "specs" - specs_root.mkdir(parents=True, exist_ok=True) - for child in operations_template_root.iterdir(): - if child.name == "template-copy-helper.md": - continue - destination_root = initiatives_root if child.name in OPERATIONS_INDEX_FILES else ops_root - destination = destination_root / child.name - if destination.exists(): - continue - if child.is_dir(): - copy_tree(child, destination) - continue - shutil.copy2(child, destination) - - (ops_root / "archive").mkdir(parents=True, exist_ok=True) - - sync_ops_root_readme(ops_root, operations_template_root) - -# endregion Filesystem Helpers - - -# region Create Initiative - -def build_initiative_placeholder_map( - args: argparse.Namespace, - target_root: Path, - prd_source: Path | None, -) -> dict[str, str]: - """Build replacements for a newly created initiative root.""" - - initiative_name = args.initiative_name or derive_initiative_name(target_root) - gate_state = args.gate_state - if args.prd_imported and gate_state == "blocked": - gate_state = "pass" - has_prd_source = prd_source is not None - validation_note = ( - "This scaffold is valid for PRD review and refinement. The source PRD was copied into `./prd.md` as-is. Review or refine it until `prd_ready: pass`, then generate a durable `roadmap.md` before any sprint directories are initialized." - if has_prd_source and not args.prd_imported - else ( - "This scaffold is valid for roadmap planning. Generate the full ordered roadmap next, review it, and set `roadmap_ready: pass` before running `prepare-sprints` or `init-sprints`." - if args.prd_imported - else "This scaffold is valid for PRD authoring, but `./prd.md` still needs the real master PRD before roadmap generation can begin." - ) - ) - next_action = ( - "Review or refine `./prd.md`, then generate `roadmap.md`. Do not initialize sprint directories until `roadmap_ready: pass`." - if has_prd_source and not args.prd_imported - else ( - "Generate `roadmap.md` from `./prd.md`, review it, and set `roadmap_ready: pass` before preparing or initializing any sprint artifacts under `./sprints/`." - if args.prd_imported - else "Import the master PRD into `./prd.md`, then generate and approve `roadmap.md` before initializing any sprint directories under `./sprints/`." - ) - ) - - return { - "REPLACE_INITIATIVE_NAME" : initiative_name, - "REPLACE_INITIATIVE_ROOT" : normalize_path(target_root), - "REPLACE_IMPORTED_ON" : args.date, - "REPLACE_GOVERNANCE_BRIDGE": "`Level 0`", - "REPLACE_GOVERNANCE_PROFILE": "`not applicable`", - "REPLACE_PHASE" : ( - args.phase - or ( - "Scaffold valid for roadmap planning; roadmap approval pending" - if args.prd_imported - else ( - "Scaffold valid for PRD review; roadmap planning pending" - if has_prd_source - else "Scaffold valid for PRD authoring; PRD import pending" - ) - ) - ), - "REPLACE_GATE_STATE" : ( - f"`prd_ready: {gate_state}`" - if ":" not in gate_state - else gate_state - ), - "REPLACE_ROADMAP_STATUS" : f"`{args.roadmap_status}`", - "REPLACE_NEXT_ACTION" : args.next_action or next_action, - "REPLACE_OWNER" : args.owner or "unassigned", - "REPLACE_VALIDATION_BASELINE": validation_note, - "REPLACE_DOCUMENTATION_STATUS": "To be confirmed during roadmap planning, sprint execution, and final audit.", - "REPLACE_EXCEPTION_POINTERS": "`none`", - "REPLACE_CURRENT_SPRINT" : "`none`", - "REPLACE_LAST_COMPLETED" : "`none`", - "REPLACE_BLOCKERS" : "`none`", - "REPLACE_CURRENT_STATUS" : "not started", - "REPLACE_NEXT_SPRINT" : "`define after roadmap approval`", - "REPLACE_RESUME_FROM" : "`review or generate roadmap from ./prd.md`", - } - - -def resolve_prd_source(prd_source: str | None) -> Path | None: - """Resolve and validate an optional source PRD path.""" - - if not prd_source: - return None - source_path = Path(prd_source).resolve() - if not source_path.exists() or not source_path.is_file(): - raise ValueError(f"Source PRD does not exist: {source_path.as_posix()}") - return source_path - - -def command_create(args: argparse.Namespace) -> int: - """Create a new initiative root under the repository operations tree.""" - - initiative_template_root = Path(args.template_root).resolve() - operations_template_root = Path(args.operations_template_root).resolve() - ops_root = Path(args.ops_root).resolve() - prd_source = resolve_prd_source(args.prd_source) - target_root = determine_target_root(args) - - if not initiative_template_root.exists() or not initiative_template_root.is_dir(): - raise ValueError(f"Initiative template root does not exist: {initiative_template_root.as_posix()}") - if not operations_template_root.exists() or not operations_template_root.is_dir(): - raise ValueError(f"Operations template root does not exist: {operations_template_root.as_posix()}") - - if args.dry_run: - print(f"dry-run: operations root would be {ops_root.as_posix()}") - print(f"dry-run: initiative root would be {target_root.as_posix()}") - if prd_source is not None: - print(f"dry-run: source PRD would be copied from {prd_source.as_posix()} to {(target_root / 'prd.md').as_posix()}") - print("dry-run: operations root bootstrap and README sync would run if needed") - return 0 - - ensure_operations_root(ops_root, operations_template_root, initiative_template_root) - ensure_directory_is_safe(target_root) - copy_initiative_template(initiative_template_root, target_root) - render_placeholders(target_root, build_initiative_placeholder_map(args, target_root, prd_source)) - if prd_source is not None: - shutil.copy2(prd_source, target_root / "prd.md") - sync_ops_root_readme(ops_root, operations_template_root) - - print(f"scaffolded initiative at {target_root.as_posix()}") - print(format_initiative_phase_status(args, prd_source)) - report_generated_placeholder_state(target_root, strict=args.strict_placeholders) - return 0 - -# endregion Create Initiative - - -# region Create Lightweight Spec - -def build_spec_placeholder_map(args: argparse.Namespace, target_root: Path) -> dict[str, str]: - """Build replacements for a newly created lightweight spec root.""" - - spec_name = args.spec_name or derive_initiative_name(target_root) - status = args.status if args.status.startswith("`") else f"`{args.status}`" - next_action = ( - args.next_action - or "Review `./spec.md`, resolve the remaining placeholders, then decide whether to execute it directly or promote it into a full initiative." - ) - return { - "REPLACE_SPEC_NAME" : spec_name, - "REPLACE_SPEC_ROOT" : normalize_path(target_root), - "REPLACE_CREATED_ON" : args.date, - "REPLACE_OWNER" : args.owner or "unassigned", - "REPLACE_SPEC_STATUS" : status, - "REPLACE_NEXT_ACTION" : next_action, - } - - -def command_create_spec(args: argparse.Namespace) -> int: - """Create a new lightweight spec root under the repository operations tree.""" - - spec_template_root = Path(args.template_root).resolve() - operations_template_root = Path(args.operations_template_root).resolve() - ops_root = Path(args.ops_root).resolve() - target_root = determine_spec_target_root(args) - - if not spec_template_root.exists() or not spec_template_root.is_dir(): - raise ValueError(f"Lightweight spec template root does not exist: {spec_template_root.as_posix()}") - if not operations_template_root.exists() or not operations_template_root.is_dir(): - raise ValueError(f"Operations template root does not exist: {operations_template_root.as_posix()}") - - if args.dry_run: - print(f"dry-run: operations root would be {ops_root.as_posix()}") - print(f"dry-run: lightweight spec root would be {target_root.as_posix()}") - print("dry-run: operations root bootstrap and README sync would run if needed") - return 0 - - ensure_operations_root(ops_root, operations_template_root, DEFAULT_INITIATIVE_TEMPLATE_ROOT) - ensure_directory_is_safe(target_root) - copy_tree(spec_template_root, target_root) - render_placeholders(target_root, build_spec_placeholder_map(args, target_root)) - sync_ops_root_readme(ops_root, operations_template_root) - - print(f"scaffolded lightweight spec at {target_root.as_posix()}") - print(format_spec_phase_status()) - report_generated_placeholder_state(target_root, strict=args.strict_placeholders) - return 0 - -# endregion Create Lightweight Spec - - -# region Initialize Sprints - -def roadmap_sprint_entries(roadmap_path: Path) -> list[RoadmapSprintEntry]: - """Extract structured sprint metadata from a roadmap document.""" - - text = roadmap_path.read_text(encoding="utf-8") - match = re.search(r"(?ms)^## Sprint Sequence\n\n(.*?)(?=^##\s|\Z)", text) - if not match: - raise ValueError("roadmap.md is missing the Sprint Sequence section.") - - current_title: str | None = None - current_data: dict[str, object] = {} - in_subtasks = False - active_field: str | None = None - entries: list[RoadmapSprintEntry] = [] - - def finalize_current() -> None: - nonlocal current_title, current_data, in_subtasks, active_field - if current_title is None: - return - - sprint_root = current_data.get("sprint_root") - if not isinstance(sprint_root, Path): - raise ValueError(f"Roadmap sprint entry is missing a valid path: {current_title}") - - goal = str(current_data.get("goal", "No explicit roadmap goal recorded.")).strip() - depends_on = str(current_data.get("depends_on", "`none`")).strip() - validation_focus = str( - current_data.get("validation_focus", "No explicit validation focus recorded.") - ).strip() - evidence_folder = str( - current_data.get("evidence_folder", f"./{(sprint_root / 'evidence').as_posix()}") - ).strip() - subtasks = tuple(current_data.get("subtasks", [])) - if not subtasks: - subtasks = ("No subtasks were listed in roadmap.md.",) - - entries.append( - RoadmapSprintEntry( - title=current_title, - sprint_root=sprint_root, - sprint_file=sprint_root / "sprint.md", - goal=strip_wrapping_backticks(goal), - depends_on=strip_wrapping_backticks(depends_on), - validation_focus=strip_wrapping_backticks(validation_focus), - evidence_folder=strip_wrapping_backticks(evidence_folder), - subtasks=tuple(strip_wrapping_backticks(item) for item in subtasks), - ) - ) - current_title = None - current_data = {} - in_subtasks = False - active_field = None - - for line in match.group(1).splitlines(): - title_match = SPRINT_ENTRY_PATTERN.match(line) - if title_match: - finalize_current() - current_title = title_match.group(1).strip() - current_data = {"subtasks": []} - in_subtasks = False - active_field = None - continue - - if current_title is None: - continue - - stripped = line.strip() - if not stripped: - continue - - path_match = SPRINT_PATH_PATTERN.match(line) - if path_match: - raw_path = strip_wrapping_backticks(path_match.group(1)) - relative = raw_path.removeprefix("./") - sprint_file = Path(relative) - if sprint_file.name == "sprint.md" and sprint_file.parts and sprint_file.parts[0] == "sprints": - current_data["sprint_root"] = Path(*sprint_file.parts[:-1]) - in_subtasks = False - active_field = None - continue - - goal_match = SPRINT_GOAL_PATTERN.match(line) - if goal_match: - current_data["goal"] = goal_match.group(1) - in_subtasks = False - active_field = "goal" - continue - - depends_match = SPRINT_DEPENDS_PATTERN.match(line) - if depends_match: - current_data["depends_on"] = depends_match.group(1) - in_subtasks = False - active_field = "depends_on" - continue - - validation_match = SPRINT_VALIDATION_PATTERN.match(line) - if validation_match: - current_data["validation_focus"] = validation_match.group(1) - in_subtasks = False - active_field = "validation_focus" - continue - - evidence_match = SPRINT_EVIDENCE_PATTERN.match(line) - if evidence_match: - current_data["evidence_folder"] = evidence_match.group(1) - in_subtasks = False - active_field = "evidence_folder" - continue - - if stripped == "- Subtasks:": - in_subtasks = True - active_field = None - continue - - if in_subtasks: - subtask_match = SPRINT_SUBTASK_PATTERN.match(line) - if subtask_match: - current_data.setdefault("subtasks", []).append(subtask_match.group(1).strip()) - continue - subtasks = current_data.get("subtasks", []) - if isinstance(subtasks, list) and subtasks and not stripped.startswith("-"): - subtasks[-1] = f"{subtasks[-1]} {stripped}".strip() - continue - in_subtasks = False - - if active_field is not None and not stripped.startswith("-"): - existing = str(current_data.get(active_field, "")).strip() - current_data[active_field] = f"{existing} {stripped}".strip() - continue - - active_field = None - - finalize_current() - - if not entries: - raise ValueError( - "No sprint paths were found in roadmap.md. Generate the full roadmap before initializing sprints." - ) - return entries - - -def ensure_sprint_directory(template_root: Path, sprint_root: Path) -> str: - """Create or validate one sprint directory from the canonical sprint template.""" - - if not sprint_root.exists(): - copy_tree(template_root, sprint_root) - return "created" - if not sprint_root.is_dir(): - raise ValueError(f"Sprint path exists and is not a directory: {sprint_root.as_posix()}") - entries = list(sprint_root.iterdir()) - if not entries: - copy_tree(template_root, sprint_root) - return "created" - - required = {"sprint.md", "closeout.md", "evidence"} - present = {path.name for path in entries} - if required.issubset(present): - synced = False - for template_child in sorted(template_root.iterdir()): - destination = sprint_root / template_child.name - if destination.exists(): - continue - if template_child.is_dir(): - copy_tree(template_child, destination) - else: - shutil.copy2(template_child, destination) - synced = True - return "synced" if synced else "existing" - missing = ", ".join(sorted(required - present)) - raise ValueError( - "Sprint directory already exists but is incomplete. " - f"Add the missing template files or clean the directory first: {sprint_root.as_posix()} ({missing})" - ) - - -def resolve_canonical_sprint_template_root() -> Path: - """Return the canonical sprint template root or raise a clear helper error.""" - - template_root = CANONICAL_SPRINT_TEMPLATE_ROOT - required_entries = {"sprint.md", "closeout.md", "decision-log.md", "evidence"} - if not template_root.exists() or not template_root.is_dir(): - raise ValueError( - "Canonical `ub-workflow` sprint template is missing or invalid: " - f"{template_root.as_posix()}" - ) - - present_entries = {path.name for path in template_root.iterdir()} - missing_entries = sorted(required_entries - present_entries) - if missing_entries: - raise ValueError( - "Canonical `ub-workflow` sprint template is missing required entries at " - f"{template_root.as_posix()}: {', '.join(missing_entries)}" - ) - return template_root - - -def ensure_initiative_rollup(initiative_root: Path) -> bool: - """Backfill rollup.md into existing initiative roots when missing.""" - - rollup_path = initiative_root / "rollup.md" - if rollup_path.exists(): - if not rollup_path.is_file(): - raise ValueError(f"Initiative rollup path exists and is not a file: {rollup_path.as_posix()}") - return False - - template_path = DEFAULT_INITIATIVE_TEMPLATE_ROOT / "rollup.md" - if not template_path.exists() or not template_path.is_file(): - raise ValueError(f"Canonical initiative rollup template is missing: {template_path.as_posix()}") - - shutil.copy2(template_path, rollup_path) - return True - - -def format_checkbox_items(items: Sequence[str]) -> str: - """Return roadmap subtasks as Markdown checklist items.""" - - if not items: - return "- [ ] No roadmap subtasks were listed." - return "\n".join(f"- [ ] {item}" for item in items) - - -def format_scope_items(entry: RoadmapSprintEntry) -> str: - """Return numbered scope items derived from the roadmap goal and subtasks.""" - - lines = [f"1. Deliver the roadmap goal: {entry.goal}."] - for index, subtask in enumerate(entry.subtasks, start=2): - lines.append(f"{index}. Complete roadmap subtask: {subtask}.") - lines.append(f"{len(lines) + 1}. Record any sprint-specific exclusions or constraints before execution begins.") - return "\n".join(lines) - - -def format_execution_slices(entry: RoadmapSprintEntry) -> str: - """Return execution-slice prompts derived from roadmap subtasks.""" - - if not entry.subtasks: - return ( - "1. Slice 01\n" - " - Objective: Replace with the first execution slice objective.\n" - " - Acceptance: Replace with how this slice will be considered done.\n" - " - Verification: Replace with the check, command, or review step for this slice.\n" - " - Dependencies: Replace with blocking inputs or `none`.\n" - " - Likely touched areas: Replace with the files, modules, or docs most likely to change." - ) - - lines: list[str] = [] - for index, subtask in enumerate(entry.subtasks, start=1): - label = f"Slice {index:02d}" - lines.extend( - [ - f"{index}. {label}", - f" - Objective: {subtask}", - " - Acceptance: Replace with the concrete done condition for this slice.", - " - Verification: Replace with the check, command, or review step for this slice.", - " - Dependencies: Replace with prior slices, external prerequisites, or `none`.", - " - Likely touched areas: Replace with the most likely files, modules, systems, or docs.", - ] - ) - return "\n".join(lines) - - -def previous_handoff_note(entry: RoadmapSprintEntry) -> str: - """Return the generated previous-sprint handoff note for a sprint.""" - - if entry.depends_on.lower() == "none": - return "No prior sprint closeout is required before this sprint begins." - return ( - f"{PENDING_HANDOFF_PREFIX} Review `{entry.depends_on}` closeout and carry forward any blockers, " - "validation changes, or repository-truth updates before execution begins." - ) - - -def next_handoff_note(next_entry: RoadmapSprintEntry | None) -> str: - """Return the generated next-sprint handoff note for a sprint.""" - - if next_entry is None: - return ( - "No next implementation sprint is planned after this one. Replace this line with final-audit " - "or archive-readiness carry-forward notes when this sprint closes." - ) - return ( - f"Roadmap next sprint: `{next_entry.title}` at `./{next_entry.sprint_file.as_posix()}`. " - "Replace this line with concrete carry-forward notes when this sprint closes." - ) - - -def build_prepare_sprint_placeholder_map( - entry: RoadmapSprintEntry, - next_entry: RoadmapSprintEntry | None, -) -> dict[str, str]: - """Build the machine-derived placeholder map for one sprint PRD.""" - - return { - "REPLACE_SPRINT_TITLE": entry.title, - "REPLACE_SPRINT_GOAL": entry.goal, - "REPLACE_SPRINT_DEPENDS_ON": entry.depends_on, - "REPLACE_SPRINT_VALIDATION_FOCUS": entry.validation_focus, - "REPLACE_SPRINT_EVIDENCE_FOLDER": entry.evidence_folder, - "REPLACE_SPRINT_SUBTASKS": format_checkbox_items(entry.subtasks), - "REPLACE_SPRINT_SCOPE_ITEMS": format_scope_items(entry), - "REPLACE_SPRINT_EXECUTION_SLICES": format_execution_slices(entry), - "REPLACE_PREVIOUS_HANDOFF_NOTE": previous_handoff_note(entry), - "REPLACE_NEXT_HANDOFF_NOTE": next_handoff_note(next_entry), - } - - -def render_prepared_sprint( - template_path: Path, - entry: RoadmapSprintEntry, - next_entry: RoadmapSprintEntry | None, -) -> str: - """Render one prepared sprint PRD from the template and roadmap entry.""" - - template_text = template_path.read_text(encoding="utf-8") - return render_text_placeholders( - template_text, - build_prepare_sprint_placeholder_map(entry, next_entry), - ) - - -def refresh_initiative_readme_for_sprints( - readme_path: Path, - first_sprint_title: str, - first_sprint_path: Path, - *, - phase: str, - gate: str, - validation_baseline: str, - documentation_status: str, -) -> None: - """Update the initiative README after sprint preparation or initialization.""" - - text = readme_path.read_text(encoding="utf-8") - updates = { - "Current phase" : phase, - "Current gate" : gate, - "Roadmap status" : "`generated`", - "Next step" : ( - f"Open the sprint-start checkpoint for {first_sprint_title} from " - f"`{normalize_path(first_sprint_path)}`; in reviewed mode, " - "preview the sprint and wait for the single later approval before " - "execution" - ), - "Active sprint" : "`none`", - "Last completed sprint": "`none`", - "Blockers" : "`none`", - } - for field, value in updates.items(): - text = update_markdown_table_value(text, field, value) - text = replace_markdown_section( - text, - "## Validation Pointers", - f"- Validation baseline: {validation_baseline}\n- Documentation sync status: {documentation_status}\n- Exception records: `none`", - ) - readme_path.write_text(text, encoding="utf-8") - - -def replace_pattern_once(text: str, pattern: str, replacement: str) -> str: - """Replace the first regex match or append the replacement if no match exists.""" - - updated, count = re.subn(pattern, replacement, text, count=1, flags=re.MULTILINE) - if count: - return updated - suffix = "" if text.endswith("\n") else "\n" - return f"{text}{suffix}{replacement}\n" - - -def refresh_roadmap_after_sprint_init(roadmap_path: Path, first_sprint_title: str, first_sprint_path: Path) -> None: - """Update roadmap state after all sprint directories have been initialized.""" - - text = roadmap_path.read_text(encoding="utf-8") - text = replace_pattern_once(text, r"^Status:\s+.+$", "Status: generated") - for candidate in (SPRINT_INIT_UNCHECKED, LEGACY_SPRINT_INIT_UNCHECKED, LEGACY_SPRINT_INIT_CHECKED): - if candidate in text: - text = text.replace(candidate, SPRINT_INIT_CHECKED, 1) - break - text = replace_pattern_once(text, r"^- Next sprint:\s+.+$", f"- Next sprint: `{first_sprint_title}`") - text = replace_pattern_once(text, r"^- Resume from:\s+.+$", f"- Resume from: `{normalize_path(first_sprint_path)}`") - roadmap_path.write_text(text, encoding="utf-8") - - -def validate_roadmap_ready(initiative_root: Path, roadmap_path: Path) -> list[str]: - """Return validation errors that block sprint initialization.""" - - errors: list[str] = [] - readme_path = initiative_root / "README.md" - if not readme_path.exists(): - errors.append("README.md is missing.") - return errors - - readme_text = readme_path.read_text(encoding="utf-8") - current_gate = read_markdown_table_value(readme_text, "Current gate") - normalized_gate = current_gate.strip("`") if current_gate else None - if normalized_gate != "roadmap_ready: pass" and not roadmap_approval_recorded(roadmap_path): - errors.append( - "README.md or roadmap.md must preserve evidence that `roadmap_ready: pass` was approved before sprint preparation or initialization can start." - ) - if unresolved_placeholder_found(roadmap_path): - errors.append("roadmap.md still contains unresolved scaffold placeholders.") - return errors - - -def resolve_resume_target(initiative_root: Path, roadmap_path: Path) -> Path | None: - """Resolve the active or next sprint path from roadmap.md when available.""" - - roadmap_text = roadmap_path.read_text(encoding="utf-8") - resume_from = read_markdown_table_value(roadmap_text, "Resume from") - if not resume_from: - return None - normalized = strip_wrapping_backticks(resume_from) - if normalized in {"none", "review or generate roadmap from ./prd.md"}: - return None - relative = normalized.removeprefix("./") - return initiative_root / Path(relative) - - -def previous_closeout_for_sprint(initiative_root: Path, sprint_path: Path) -> Path | None: - """Return the previous sprint closeout path for a given sprint when one exists.""" - - roadmap_path = initiative_root / "roadmap.md" - entries = roadmap_sprint_entries(roadmap_path) - try: - relative = sprint_path.resolve().relative_to(initiative_root.resolve()) - except ValueError: - relative = sprint_path - for index, entry in enumerate(entries): - if entry.sprint_file == relative: - if index == 0: - return None - previous = initiative_root / entries[index - 1].sprint_root / "closeout.md" - return previous if previous.exists() else None - return None - - -def resolve_resume_file_order(initiative_root: Path, sprint_path: Path | None = None) -> list[Path]: - """Return the minimal file order needed to resume an initiative safely.""" - - roadmap_path = initiative_root / "roadmap.md" - readme_path = initiative_root / "README.md" - prd_path = initiative_root / "prd.md" - target_sprint = sprint_path or resolve_resume_target(initiative_root, roadmap_path) - - ordered: list[Path] = [roadmap_path] - previous_closeout: Path | None = None - if target_sprint is not None: - previous_closeout = previous_closeout_for_sprint(initiative_root, target_sprint) - if previous_closeout is not None: - ordered.append(previous_closeout) - if target_sprint.exists(): - ordered.append(target_sprint) - ordered.append(readme_path) - if ( - prd_path.exists() - and ( - target_sprint is None - or not target_sprint.exists() - or ( - sprint_document_has_blocking_placeholders(target_sprint) - and previous_closeout is None - ) - ) - ): - ordered.append(prd_path) - return ordered - - -def command_init_sprints(args: argparse.Namespace) -> int: - """Create the full sprint set from roadmap path entries.""" - - initiative_root = Path(args.initiative_root).resolve() - roadmap_path = initiative_root / "roadmap.md" - sprint_template_root = resolve_canonical_sprint_template_root() - if not roadmap_path.exists(): - raise ValueError(f"Initiative roadmap does not exist: {roadmap_path.as_posix()}") - - readiness_errors = validate_roadmap_ready(initiative_root, roadmap_path) - if readiness_errors: - message = "Sprint initialization blocked because the roadmap is not ready:\n- " + "\n- ".join(readiness_errors) - raise ValueError(message) - - entries = roadmap_sprint_entries(roadmap_path) - if args.dry_run: - print(f"dry-run: {len(entries)} sprint directories would be initialized under {initiative_root.as_posix()}") - return 0 - - created = 0 - synced = 0 - rollup_created = ensure_initiative_rollup(initiative_root) - first_entry = entries[0] - for entry in entries: - status = ensure_sprint_directory(sprint_template_root, initiative_root / entry.sprint_root) - if status == "created": - created += 1 - elif status == "synced": - synced += 1 - - readme_text = (initiative_root / "README.md").read_text(encoding="utf-8") - current_gate = read_markdown_table_value(readme_text, "Current gate") - normalized_gate = current_gate.strip("`") if current_gate else "" - phase = "Roadmap approved, sprint initialization complete" - gate = "`roadmap_ready: pass`" - validation_baseline = "The master PRD, full ordered roadmap, and all planned sprint folders are now in place." - documentation_status = "No sprint-specific documentation updates are required yet because execution has not started." - if normalized_gate == "sprint_content_ready: pass": - phase = "Sprint set initialized, sprint pack ready for execution review" - gate = "`sprint_content_ready: pass`" - validation_baseline = "The sprint pack is prepared and all planned sprint folders are now in place." - documentation_status = "Sprint PRDs are prepared and execution has not started yet." - - refresh_initiative_readme_for_sprints( - initiative_root / "README.md", - first_entry.title, - initiative_root / first_entry.sprint_file, - phase=phase, - gate=gate, - validation_baseline=validation_baseline, - documentation_status=documentation_status, - ) - refresh_roadmap_after_sprint_init( - roadmap_path, - first_entry.title, - initiative_root / first_entry.sprint_file, - ) - - print( - f"initialized {len(entries)} sprint directories " - f"({created} newly created, {synced} additive template syncs, " - f"{1 if rollup_created else 0} rollup backfilled)" - ) - report_generated_placeholder_state(initiative_root, strict=args.strict_placeholders) - return 0 - - -def command_prepare_sprints(args: argparse.Namespace) -> int: - """Prepare sprint PRDs from roadmap metadata before execution begins.""" - - initiative_root = Path(args.initiative_root).resolve() - roadmap_path = initiative_root / "roadmap.md" - sprint_template_root = resolve_canonical_sprint_template_root() - sprint_template_path = sprint_template_root / "sprint.md" - if not roadmap_path.exists(): - raise ValueError(f"Initiative roadmap does not exist: {roadmap_path.as_posix()}") - - readiness_errors = validate_roadmap_ready(initiative_root, roadmap_path) - if readiness_errors: - message = "Sprint preparation blocked because the roadmap is not ready:\n- " + "\n- ".join(readiness_errors) - raise ValueError(message) - - entries = roadmap_sprint_entries(roadmap_path) - if args.dry_run: - print(f"dry-run: {len(entries)} sprint PRDs would be prepared under {initiative_root.as_posix()}") - for entry in entries: - print( - "dry-run: " - f"{entry.title} | goal={entry.goal} | depends_on={entry.depends_on} | " - f"validation_focus={entry.validation_focus} | subtasks={len(entry.subtasks)} | " - f"evidence={entry.evidence_folder}" - ) - return 0 - - created = 0 - synced = 0 - rendered = 0 - preserved = 0 - rollup_created = ensure_initiative_rollup(initiative_root) - first_entry = entries[0] - for index, entry in enumerate(entries): - sprint_root = initiative_root / entry.sprint_root - status = ensure_sprint_directory(sprint_template_root, sprint_root) - if status == "created": - created += 1 - elif status == "synced": - synced += 1 - - sprint_path = initiative_root / entry.sprint_file - if sprint_path.exists() and not sprint_document_has_blocking_placeholders(sprint_path): - preserved += 1 - continue - - next_entry = entries[index + 1] if index + 1 < len(entries) else None - sprint_path.write_text( - render_prepared_sprint(sprint_template_path, entry, next_entry), - encoding="utf-8", - ) - rendered += 1 - - refresh_initiative_readme_for_sprints( - initiative_root / "README.md", - first_entry.title, - initiative_root / first_entry.sprint_file, - phase="Sprint pack prepared, awaiting Sprint 01 execution", - gate="`sprint_content_ready: pass`", - validation_baseline="The sprint pack now contains roadmap-derived sprint PRDs with explicit handoff markers and machine-derived context.", - documentation_status="Sprint PRDs are prepared for review before execution. Helper and template semantics should be validated before relying on them for new initiatives.", - ) - refresh_roadmap_after_sprint_init( - roadmap_path, - first_entry.title, - initiative_root / first_entry.sprint_file, - ) - - print( - f"prepared {len(entries)} sprint PRDs " - f"({created} directories created, {synced} additive template syncs, " - f"{rendered} rendered, {preserved} preserved, " - f"{1 if rollup_created else 0} rollup backfilled)" - ) - report_generated_placeholder_state(initiative_root, strict=args.strict_placeholders) - return 0 - -# endregion Initialize Sprints - - -# region Archive Initiative - -def unresolved_placeholder_found(path: Path) -> bool: - """Return True when a control file still contains obvious scaffold placeholders.""" - - text = path.read_text(encoding="utf-8") - initiative_root = ( - path.parent - if path.name in {"README.md", "roadmap.md", "prd.md", "rollup.md", "retained-note.md"} - else path.parents[2] - ) - return bool(required_placeholder_markers(text, path, initiative_root)) - - -def overall_checklist_is_complete(roadmap_path: Path) -> bool: - """Return True when the roadmap overall checklist has no unchecked items.""" - - text = roadmap_path.read_text(encoding="utf-8") - match = re.search(r"(?ms)^## Overall Checklist\n\n(.*?)(?=^##\s|\Z)", text) - if not match: - return False - return "- [ ]" not in match.group(1) - - -def roadmap_approval_recorded(roadmap_path: Path) -> bool: - """Return True when roadmap approval is visibly recorded in roadmap.md.""" - - text = roadmap_path.read_text(encoding="utf-8") - return "- [x] Roadmap reviewed and approved with `roadmap_ready: pass`" in text - - -def validate_archive_readiness(initiative_root: Path) -> list[str]: - """Return validation errors that block archive-on-request.""" - - errors: list[str] = [] - readme_path = initiative_root / "README.md" - roadmap_path = initiative_root / "roadmap.md" - rollup_path = initiative_root / "rollup.md" - retained_note_path = initiative_root / "retained-note.md" - if not readme_path.exists(): - errors.append("README.md is missing.") - if not roadmap_path.exists(): - errors.append("roadmap.md is missing.") - if not rollup_path.exists(): - errors.append("rollup.md is missing.") - if not retained_note_path.exists(): - errors.append("retained-note.md is missing.") - if errors: - return errors - - readme_text = readme_path.read_text(encoding="utf-8") - current_gate = read_markdown_table_value(readme_text, "Current gate") - normalized_gate = current_gate.strip("`") if current_gate else None - if normalized_gate not in {"archive_ready: pass", "initiative_complete: pass"}: - errors.append( - "README.md must record `archive_ready: pass` or `initiative_complete: pass` before archive can start." - ) - - if not overall_checklist_is_complete(roadmap_path): - errors.append("roadmap.md still has unchecked items in the Overall Checklist section.") - if unresolved_placeholder_found(readme_path): - errors.append("README.md still contains unresolved scaffold placeholders.") - if unresolved_placeholder_found(retained_note_path): - errors.append("retained-note.md still contains unresolved scaffold placeholders.") - return errors - - -def discover_ops_root(initiative_root: Path, explicit_ops_root: str | None) -> Path: - """Resolve the owning operations root for an initiative.""" - - if explicit_ops_root: - return Path(explicit_ops_root).resolve() - parent = initiative_root.parent - if parent.name != "initiatives": - raise ValueError("Provide --ops-root when archiving an initiative outside ./initiatives/.") - return parent.parent.resolve() - - -def command_archive(args: argparse.Namespace) -> int: - """Archive a completed initiative only when explicitly requested.""" - - initiative_root = Path(args.initiative_root).resolve() - if not initiative_root.exists() or not initiative_root.is_dir(): - raise ValueError(f"Initiative root does not exist: {initiative_root.as_posix()}") - - errors = validate_archive_readiness(initiative_root) - if errors: - message = "Archive blocked because the initiative is not complete:\n- " + "\n- ".join(errors) - raise ValueError(message) - - ops_root = discover_ops_root(initiative_root, args.ops_root) - archive_root = ops_root / "archive" / initiative_root.name - if archive_root.exists(): - raise ValueError(f"Archive destination already exists: {archive_root.as_posix()}") - - if args.dry_run: - print(f"dry-run: initiative would be moved to {archive_root.as_posix()}") - return 0 - - archive_root.parent.mkdir(parents=True, exist_ok=True) - shutil.move(initiative_root.as_posix(), archive_root.as_posix()) - sync_ops_root_readme(ops_root, Path(args.operations_template_root).resolve()) - - print(f"archived initiative to {archive_root.as_posix()}") - return 0 - -# endregion Archive Initiative - - -# region Argument Parsing - -def build_parser() -> argparse.ArgumentParser: - """Build the command-line parser for the initiative workflow helper.""" - - parser = argparse.ArgumentParser(description=__doc__) - subparsers = parser.add_subparsers(dest="command") - - create_parser = subparsers.add_parser("create", help="Create a new initiative root") - create_parser.add_argument("target", nargs="?", help="Initiative slug or explicit target path") - create_parser.add_argument("--ops-root", default=str(DEFAULT_OPS_ROOT), help="Operations root to bootstrap and use") - create_parser.add_argument( - "--template-root", - default=str(DEFAULT_INITIATIVE_TEMPLATE_ROOT), - help="Initiative control-file template directory to copy from", - ) - create_parser.add_argument( - "--operations-template-root", - default=str(DEFAULT_OPERATIONS_TEMPLATE_ROOT), - help="Operations-root template directory to copy from", - ) - create_parser.add_argument("--initiative-name", help="Display name written into the scaffold") - create_parser.add_argument("--owner", help="Initiative owner") - create_parser.add_argument( - "--date", - default=datetime.now(timezone.utc).date().isoformat(), - help="Date stamp used in generated paths and README state", - ) - create_parser.add_argument("--phase", help="Initial initiative phase") - create_parser.add_argument( - "--gate-state", - default="blocked", - help="Initial initiative gate state; plain values are wrapped as `prd_ready: `", - ) - create_parser.add_argument("--roadmap-status", default="not started", help="Initial roadmap status string") - create_parser.add_argument("--next-action", help="Initial next-action value written into README.md") - create_parser.add_argument( - "--prd-source", - help="Source PRD file to copy into the initiative root as ./prd.md", - ) - create_parser.add_argument( - "--prd-imported", - action="store_true", - help="Mark the PRD as already execution-ready after copy/import", - ) - create_parser.add_argument( - "--strict-placeholders", - action="store_true", - help="Fail after create when generated output still has required unresolved placeholders", - ) - create_parser.add_argument("--dry-run", action="store_true", help="Report the resolved create operation without writing files") - - create_spec_parser = subparsers.add_parser("create-spec", help="Create a new lightweight spec root") - create_spec_parser.add_argument("target", nargs="?", help="Lightweight spec slug or explicit target path") - create_spec_parser.add_argument("--ops-root", default=str(DEFAULT_OPS_ROOT), help="Operations root to bootstrap and use") - create_spec_parser.add_argument( - "--template-root", - default=str(DEFAULT_SPEC_TEMPLATE_ROOT), - help="Lightweight spec template directory to copy from", - ) - create_spec_parser.add_argument( - "--operations-template-root", - default=str(DEFAULT_OPERATIONS_TEMPLATE_ROOT), - help="Operations-root template directory to copy from", - ) - create_spec_parser.add_argument("--spec-name", help="Display name written into the lightweight spec scaffold") - create_spec_parser.add_argument("--owner", help="Lightweight spec owner") - create_spec_parser.add_argument( - "--date", - default=datetime.now(timezone.utc).date().isoformat(), - help="Date stamp used in generated paths and spec state", - ) - create_spec_parser.add_argument("--status", default="draft", help="Initial lightweight spec status string") - create_spec_parser.add_argument("--next-action", help="Initial next-action value written into spec.md") - create_spec_parser.add_argument( - "--strict-placeholders", - action="store_true", - help="Fail after create-spec when generated output still has required unresolved placeholders", - ) - create_spec_parser.add_argument("--dry-run", action="store_true", help="Report the resolved create-spec operation without writing files") - - prepare_parser = subparsers.add_parser( - "prepare-sprints", - help="Prepare sprint PRDs from roadmap metadata before execution begins", - ) - prepare_parser.add_argument("initiative_root", help="Initiative root containing roadmap.md") - prepare_parser.add_argument( - "--strict-placeholders", - action="store_true", - help="Fail after sprint preparation when generated output still has required unresolved placeholders", - ) - prepare_parser.add_argument("--dry-run", action="store_true", help="Report sprint preparation without writing files") - - init_parser = subparsers.add_parser("init-sprints", help="Initialize sprint directories from roadmap paths") - init_parser.add_argument("initiative_root", help="Initiative root containing roadmap.md") - init_parser.add_argument( - "--strict-placeholders", - action="store_true", - help="Fail after sprint initialization when generated output still has required unresolved placeholders", - ) - init_parser.add_argument("--dry-run", action="store_true", help="Report sprint initialization without writing files") - - archive_parser = subparsers.add_parser("archive", help="Archive a completed initiative root") - archive_parser.add_argument("initiative_root", help="Initiative root to archive") - archive_parser.add_argument("--ops-root", help="Override the owning operations root") - archive_parser.add_argument( - "--operations-template-root", - default=str(DEFAULT_OPERATIONS_TEMPLATE_ROOT), - help="Operations-root template directory used to sync README.md after archive", - ) - archive_parser.add_argument("--dry-run", action="store_true", help="Report the archive move without writing files") - - return parser - - -def rewrite_legacy_arguments(argv: Sequence[str]) -> list[str]: - """Keep the original single-argument create invocation working.""" - - if len(argv) < 2: - return list(argv) - command = argv[1] - if command in KNOWN_COMMANDS or command.startswith("-"): - return list(argv) - return [argv[0], "create", *argv[1:]] - - -def main(argv: Sequence[str] | None = None) -> int: - """Execute the initiative workflow helper.""" - - raw_argv = list(argv) if argv is not None else None - adjusted_argv = rewrite_legacy_arguments(raw_argv or __import__("sys").argv) - parser = build_parser() - args = parser.parse_args(adjusted_argv[1:]) - - try: - if args.command == "create": - return command_create(args) - if args.command == "create-spec": - return command_create_spec(args) - if args.command == "prepare-sprints": - return command_prepare_sprints(args) - if args.command == "init-sprints": - return command_init_sprints(args) - if args.command == "archive": - return command_archive(args) - except ValueError as exc: - parser.exit(1, f"{exc}\n") - - parser.print_help() - return 1 - -# endregion Argument Parsing - - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/.agents/skills/ub-workflow/scripts/scaffold_workflow.py b/.agents/skills/ub-workflow/scripts/scaffold_workflow.py new file mode 100644 index 0000000..150a266 --- /dev/null +++ b/.agents/skills/ub-workflow/scripts/scaffold_workflow.py @@ -0,0 +1,1171 @@ +#!/usr/bin/env python3 +"""Scaffold portable ub-workflow artifacts.""" + +import argparse +from dataclasses import dataclass +from datetime import date, datetime, timezone +from pathlib import Path +import re +import shutil + +SKILL_ROOT = Path(__file__).resolve().parents[1] +DEFAULT_OPS_ROOT = Path(".ub-workflows") +INITIATIVE_TEMPLATE_ROOT = SKILL_ROOT / "assets" / "initiative-template" +SPRINT_TEMPLATE_ROOT = INITIATIVE_TEMPLATE_ROOT / "sprint-template" +OPERATIONS_ROOT_TEMPLATE = SKILL_ROOT / "assets" / "operations-root" +GITKEEP = ".gitkeep" +ROOT_AGENTS = "AGENTS.md" +SOURCE_ATLAS = "SOURCE_ATLAS.md" +UB_WORKFLOW_AGENTS_START = "" +UB_WORKFLOW_AGENTS_END = "" +TEXT_SUFFIXES = {".md", ".txt", ".yaml", ".yml", ".json"} +SOURCE_SCAN_SKIP_DIRS = { + ".agents", + ".cache", + ".git", + ".mypy_cache", + ".pytest_cache", + ".ruff_cache", + ".ub-workflows", + ".venv", + "__pycache__", + "build", + "dist", + "donors", + "node_modules", +} +SOURCE_SCAN_PRIORITY = ( + "src", + "tests", + "docs", + "scripts", + "tools", + "app", + "apps", + "packages", + "lib", +) +WAVE_RE = re.compile(r"^w(?P\d{2})-") +INIT_RE = re.compile(r"^i(?P\d{2})-") +SPRINT_RE = re.compile(r"^w\d{2}-i\d{2}-s(?P\d{2})-") +WAVE_DISCOVERY_RE = re.compile(r"^w\d{2}-d(?P\d{2})-") +INIT_DISCOVERY_RE = re.compile(r"^w\d{2}-i\d{2}-d(?P\d{2})-") +DATE_RE = re.compile(r"^\d{4}-\d{2}-\d{2}-") +MACHINE_PLACEHOLDER_RE = re.compile(r"\bREPLACE_[A-Z0-9_]+\b") +HUMAN_PLACEHOLDER_RE = re.compile(r"Replace with\b") +CODE_FENCE_RE = re.compile(r"^\s*(```|~~~)") +OPTION_HEADING_RE = re.compile(r"^(?P#{2,3})\s+(?P.+?)\s*$") +OPTION_FIELD_RE = re.compile(r"^-\s+(?P<label>[A-Za-z ]+):") +OPTION_DATE_RE = re.compile(r"^-\s+Last reviewed:\s+(?P<date>\d{4}-\d{2}-\d{2})\.") +STATUS_ACTIVE_INITIATIVE_RE = re.compile(r"^- Active initiative:\s+`(?P<path>[^`]+)`\.?\s*$") +STATUS_INITIATIVE_ROADMAP_RE = re.compile(r"^- Initiative roadmap:\s+`(?P<path>[^`]+)`\.?\s*$") +REQUIRED_OPTION_FIELDS = { + "Assignment confidence", + "Evidence links", + "Last reviewed", + "Promotion trigger", + "Revalidation rule", + "Suggested home", + "Why it matters", +} +FORBIDDEN_OPTION_LANE_PREFIXES = ( + "archive", + "archived", + "closed", + "completed", + "done", +) +PRODUCT_OPTION_MARKERS = ( + "W12", + "W13", + "First-Party Context Compaction", + "Memory Provider", + "External AgentRuntime", + "AgentHarness", +) + + +@dataclass(frozen=True) +class PlaceholderFinding: + workflow_root: Path + file_path: Path + line_number: int + category: str + severity: str + marker: str + line_text: str + + +@dataclass(frozen=True) +class OptionCard: + file_path: Path + line_number: int + title: str + fields: frozenset[str] + last_reviewed: date | None + + +@dataclass(frozen=True) +class OptionsFinding: + workflow_root: Path + file_path: Path + line_number: int | None + category: str + severity: str + message: str + + +def slugify(value: str) -> str: + slug = re.sub(r"[^a-z0-9]+", "-", value.strip().lower()).strip("-") + return slug or "workflow" + + +def wave_id_from_root(wave_root: Path) -> str: + match = WAVE_RE.match(wave_root.name) + if not match: + raise ValueError(f"Wave root must be named wNN-slug: {wave_root}") + return f"w{match.group('num')}" + + +def initiative_id_from_root(initiative_root: Path) -> str: + match = INIT_RE.match(initiative_root.name) + if not match: + raise ValueError(f"Initiative root must be named iNN-slug: {initiative_root}") + return f"i{match.group('num')}" + + +def owning_wave_root(path: Path) -> Path: + current = path.resolve() + for candidate in [current, *current.parents]: + if WAVE_RE.match(candidate.name) and (candidate / "wave.md").exists(): + return candidate + raise ValueError(f"Unable to find owning wave root for {path}") + + +def next_number(container: Path, pattern: re.Pattern[str]) -> int: + max_num = 0 + if container.exists(): + for child in container.iterdir(): + match = pattern.match(child.name) + if match: + max_num = max(max_num, int(match.group("num"))) + return max_num + 1 + + +def ensure_empty(target: Path) -> None: + if target.exists() and any(target.iterdir() if target.is_dir() else [target]): + raise ValueError(f"Refusing to overwrite non-empty target: {target}") + target.mkdir(parents=True, exist_ok=True) + + +def add_gitkeep(container: Path) -> None: + container.mkdir(parents=True, exist_ok=True) + if not any(child.name != GITKEEP for child in container.iterdir()): + (container / GITKEEP).touch() + + +def remove_gitkeep(container: Path) -> None: + gitkeep = container / GITKEEP + if gitkeep.exists(): + gitkeep.unlink() + + +def refresh_gitkeep(container: Path) -> None: + if any(child.name != GITKEEP for child in container.iterdir()): + remove_gitkeep(container) + else: + add_gitkeep(container) + + +def discover_workflow_root(scan_root: Path) -> Path: + root = scan_root.resolve() + if root.name == ".ub-workflows" and (root / "status.md").exists(): + return root + if (root / ".ub-workflows" / "status.md").exists(): + return root / ".ub-workflows" + for candidate in root.parents: + if candidate.name == ".ub-workflows" and (candidate / "status.md").exists(): + return candidate + nested = candidate / ".ub-workflows" + if (nested / "status.md").exists(): + return nested + raise ValueError(f"Unable to find .ub-workflows root from {scan_root}") + + +def path_from_workflow_root(workflow_root: Path, raw_path: str) -> Path: + candidate = Path(raw_path) + if candidate.is_absolute(): + return candidate + return workflow_root / candidate + + +def active_initiative_root(workflow_root: Path) -> Path | None: + status_path = workflow_root / "status.md" + if not status_path.exists(): + return None + for line in status_path.read_text(encoding="utf-8").splitlines(): + match = STATUS_ACTIVE_INITIATIVE_RE.match(line.strip()) + if match: + return path_from_workflow_root(workflow_root, match.group("path")) + return None + + +def active_initiative_roadmap(workflow_root: Path) -> Path | None: + status_path = workflow_root / "status.md" + if status_path.exists(): + for line in status_path.read_text(encoding="utf-8").splitlines(): + match = STATUS_INITIATIVE_ROADMAP_RE.match(line.strip()) + if match: + return path_from_workflow_root(workflow_root, match.group("path")) + initiative_root = active_initiative_root(workflow_root) + return initiative_root / "roadmap.md" if initiative_root else None + + +def option_board_paths(workflow_root: Path, *, include_history: bool = False) -> list[Path]: + paths = [workflow_root / "options.md"] + active_root = active_initiative_root(workflow_root) + if active_root is not None: + paths.append(active_root / "options.md") + if include_history: + paths.extend(sorted((workflow_root / "waves").glob("w??-*/initiatives/i??-*/options.md"))) + seen: set[Path] = set() + unique_paths: list[Path] = [] + for path in paths: + resolved = path.resolve() + if resolved in seen: + continue + seen.add(resolved) + unique_paths.append(path) + return unique_paths + + +def render(text: str, replacements: dict[str, str]) -> str: + for key, value in replacements.items(): + text = text.replace(key, value) + return text + + +def copy_rendered_tree( + source: Path, + target: Path, + replacements: dict[str, str], + *, + skip_parts: set[str] | None = None, +) -> None: + excluded = skip_parts or set() + for item in source.rglob("*"): + relative = item.relative_to(source) + if any(part in excluded for part in relative.parts): + continue + destination = target / relative + if item.is_dir(): + destination.mkdir(parents=True, exist_ok=True) + continue + destination.parent.mkdir(parents=True, exist_ok=True) + if item.suffix in TEXT_SUFFIXES or item.name in {"AGENTS.md", "README.md"}: + destination.write_text( + render(item.read_text(encoding="utf-8"), replacements), encoding="utf-8" + ) + else: + shutil.copy2(item, destination) + + +def detected_source_roots(project_root: Path) -> list[Path]: + roots = [project_root / name for name in SOURCE_SCAN_PRIORITY if (project_root / name).is_dir()] + priority_names = {path.name for path in roots} + for child in sorted(project_root.iterdir(), key=lambda path: path.name): + if not child.is_dir(): + continue + if child.name in SOURCE_SCAN_SKIP_DIRS or child.name.startswith("."): + continue + if child.name in priority_names: + continue + if (child / ROOT_AGENTS).exists() or any(child.glob("*.py")): + roots.append(child) + return roots + + +def source_route_lines(project_root: Path) -> list[str]: + lines: list[str] = [] + for source_root in detected_source_roots(project_root): + relative = source_root.relative_to(project_root).as_posix() + local_agents = source_root / ROOT_AGENTS + start = f"`{relative}/AGENTS.md`" if local_agents.exists() else f"`{relative}/`" + lines.append(f"- `{relative}/`: start at {start}.") + if not lines: + lines.append("- No source roots detected yet. Add routes when source boundaries exist.") + return lines + + +def build_source_atlas(project_root: Path) -> str: + return ( + "# Source Atlas\n\n" + "This file routes source-code work before agents read implementation files. " + "It is seeded once by `ub-workflow` bootstrap from visible project roots " + "and then maintained when source boundaries change.\n\n" + "## First-Read Order\n\n" + "For non-trivial source work:\n\n" + "1. Root `AGENTS.md`.\n" + "2. `.ub-workflows/status.md`.\n" + "3. `SOURCE_ATLAS.md`.\n" + "4. Nearest relevant folder `AGENTS.md` when one exists.\n" + "5. Selected source files and tests.\n" + "6. `.ub-workflows/vision.md` only when product direction matters.\n\n" + "Do not read unrelated folder guidance unless the task crosses that boundary.\n\n" + "## Map Use Rule\n\n" + "Module maps are routing aids, not source truth. Use them to choose files " + "to open first, then inspect source and tests with fast local search before " + "changing behavior. If source ownership changes, update this atlas in the " + "same change.\n\n" + "## Detected Source Routes\n\n" + "\n".join(source_route_lines(project_root)) + "\n\n" + "## Workflow Route\n\n" + "- Workflow state, waves, discoveries, initiatives, sprints, and source " + "packs: start at `.ub-workflows/WORKFLOW_ATLAS.md`, then " + "`.ub-workflows/AGENTS.md`.\n\n" + "## Local Guidance Policy\n\n" + "Local `AGENTS.md` files should answer only what the folder owns, when work " + "starts there, local boundaries, what to inspect before editing, likely " + "tests, and what to avoid. Add local guidance only when a folder has a " + "meaningful responsibility boundary, rule set, or repeated navigation cost.\n\n" + "## Source Route Note\n\n" + "Before editing, identify the owning folder, local guidance read, expected " + "source files, expected tests, and boundaries intentionally avoided.\n\n" + "## Maintenance\n\n" + "Update this file and the nearest relevant folder `AGENTS.md` when a change " + "adds, removes, renames, or moves a source boundary, plugin lane, public API " + "area, runtime/protocol/host responsibility, major package, or test topology." + "\n" + ) + + +def build_root_agents_section() -> str: + return ( + f"{UB_WORKFLOW_AGENTS_START}\n" + "## UB Workflow Routing\n\n" + "- Before substantial work, read `.ub-workflows/status.md`.\n" + "- For non-trivial source work, read `SOURCE_ATLAS.md` and then the nearest " + "relevant folder `AGENTS.md`.\n" + "- Use `.ub-workflows/vision.md` when product direction matters.\n" + "- Use `.ub-workflows/options.md` for wave or initiative transition, " + "future-work lookup, or option promotion.\n" + "- Use `.ub-workflows/WORKFLOW_ATLAS.md` for workflow-artifact routing.\n" + "- Use `.ub-workflows/SOURCE_PACK_ATLAS.md` before opening retained source " + "packs.\n" + "- When forecast pressure appears, present options and tradeoffs, then wait " + "for explicit operator decision before expanding scope.\n" + "- Keep reusable workflow mechanics in the shared `ub-workflow` skill; keep " + "repo overlays focused on local facts, boundaries, and validation commands.\n" + f"{UB_WORKFLOW_AGENTS_END}" + ) + + +def patch_root_agents(project_root: Path) -> None: + path = project_root / ROOT_AGENTS + section = build_root_agents_section() + if path.exists(): + text = path.read_text(encoding="utf-8").rstrip() + pattern = re.compile( + re.escape(UB_WORKFLOW_AGENTS_START) + r".*?" + re.escape(UB_WORKFLOW_AGENTS_END), + re.DOTALL, + ) + updated = ( + pattern.sub(section, text) if pattern.search(text) else f"{text}\n\n{section}" + ) + else: + updated = f"# Agent Instructions\n\n{section}" + path.write_text(f"{updated.rstrip()}\n", encoding="utf-8") + + +def command_bootstrap(args: argparse.Namespace) -> int: + ops_root = Path(args.ops_root).resolve() + project_root = ops_root.parent + ensure_empty(ops_root) + add_gitkeep(ops_root / "source-packs") + add_gitkeep(ops_root / "waves") + source_atlas = project_root / SOURCE_ATLAS + if not source_atlas.exists(): + source_atlas.write_text(build_source_atlas(project_root), encoding="utf-8") + patch_root_agents(project_root) + copy_rendered_tree(OPERATIONS_ROOT_TEMPLATE, ops_root, {}) + (ops_root / "vision.md").write_text( + "# Product Vision\n\n" + "## Product Promise\n\nReplace with the durable product promise.\n\n" + "## Audiences\n\n1. Replace with the first audience.\n\n" + "## Durable Principles\n\n1. Replace with the first principle.\n\n" + "## Capability Pillars\n\n1. Replace with the first capability pillar.\n\n" + "## Evidence Questions\n\n1. Replace with the first evidence question.\n\n" + "## Change Rule\n\nUpdate this vision only through reviewed discovery, closeout, transition, " + "or an explicit product decision.\n", + encoding="utf-8", + ) + (ops_root / "options.md").write_text( + "# Product Options Board\n\n" + "This board preserves curated product-level, future-wave, and " + "unknown-owner options before commitment. It is not a backlog ledger, " + "completion history, or execution authorization surface.\n\n" + "Order is document order within each horizon lane. Order means current " + "review preference, not delivery commitment.\n\n" + "## Board Rules\n\n" + "- Keep cards compact; move deep context into source packs, discoveries, " + "or owner artifacts.\n" + "- Remove a card after it is promoted, rejected, merged, or completed and " + "the receiving artifact records the durable trace.\n" + "- Revalidate every card before activation; stale cards are not executable.\n" + "- If this file becomes hard to scan quickly, prune, merge, or move context " + "back into source packs before adding more cards.\n" + "- During wave or initiative transition, review this board plus unresolved " + "local initiative options before selecting the next route.\n\n" + "## Next Wave Candidate\n\nNo active cards.\n\n" + "## Probable Later Wave\n\nNo active cards.\n\n" + "## Unassigned Product Option\n\nNo active cards.\n\n" + "## Update Rules\n\n" + "Add only options that are likely to matter after context loss and do not " + "yet belong in a committed roadmap. Remove cards once the receiving " + "artifact owns the trace.\n", + encoding="utf-8", + ) + (ops_root / "status.md").write_text( + "# Workflow Status\n\n" + "## Current Product Posture\n\nReplace with current posture.\n\n" + "## Current Operating State\n\nState: initialized.\n\n" + "## WIP State\n\nNo active discovery or delivery sprint.\n\n" + "## Active Pointers\n\nNo active wave yet.\n\n" + "## Blockers\n\nNone.\n\n" + "## Wave Sequence\n\nNo waves yet.\n\n" + "## Conditional Candidate Tracks\n\nNo candidates yet.\n\n" + "## Retained-Context Routes\n\nUse `SOURCE_PACK_ATLAS.md` before opening source packs.\n\n" + "## Next Allowed Action\n\nCreate or activate the first wave.\n", + encoding="utf-8", + ) + (ops_root / "WORKFLOW_ATLAS.md").write_text( + "# Workflow Atlas\n\n" + "Portable workflow rules live in the `ub-workflow` skill. This atlas routes " + "project-local workflow artifacts to their owning files.\n\n" + "## Owners\n\n" + "- `vision.md`: product north star.\n" + "- `options.md`: curated product-level, future-wave, and unknown-owner options before commitment.\n" + "- `status.md`: current posture, active pointers, WIP, blockers, and next action.\n" + "- `waves/wNN-*/`: wave, initiative, local options, forecast, discovery, sprint, and evidence owners.\n" + "- `source-packs/YYYY-MM-DD-*/`: retained context only.\n", + encoding="utf-8", + ) + (ops_root / "SOURCE_PACK_ATLAS.md").write_text( + "# Source Pack Atlas\n\n" + "Source packs are dated retained context. Search first, open the owning " + "`00-readme.md`, then open at most one named section file unless the " + "current artifact records a broader read receipt.\n", + encoding="utf-8", + ) + print(ops_root.as_posix()) + return 0 + + +def command_create_wave(args: argparse.Namespace) -> int: + ops_root = Path(args.ops_root).resolve() + wave_id = args.wave_id.lower() + if not re.fullmatch(r"w\d{2}", wave_id): + raise ValueError("wave_id must use wNN format") + wave_root = ops_root / "waves" / f"{wave_id}-{slugify(args.slug)}" + ensure_empty(wave_root) + remove_gitkeep(ops_root / "waves") + add_gitkeep(wave_root / "discoveries") + add_gitkeep(wave_root / "initiatives") + add_gitkeep(wave_root / "source-packs") + (wave_root / "wave.md").write_text( + f"# Wave {wave_id.upper()}: {args.slug.replace('-', ' ').title()}\n\n" + "## Outcome\n\nReplace with the wave outcome.\n\n" + "## Why Now\n\nReplace with the reason this wave matters now.\n\n" + "## Scope Boundaries\n\n1. Replace with the first boundary.\n\n" + "## Bet Framing\n\n" + "- Appetite: Replace with wave appetite.\n" + "- Success evidence: Replace with success evidence.\n" + "- Circuit breaker: Replace with stop or reroute condition.\n" + "- Deferral path: Replace with where not-now work lives.\n\n" + "## Outcome Signals\n\n" + "- Product/user signal: Replace with product, user, customer, or operator value signal.\n" + "- Delivery/flow signal: Replace with delivery, WIP, blocked-time, or route-clarity signal.\n" + "- Quality/stability signal: Replace with correctness, reliability, validation, or failure-handling signal.\n" + "- Context/evidence cost signal: Replace with context, evidence, or recovery-cost signal.\n\n" + "## Forecast And Appetite\n\n" + "- Appetite: Replace with wave appetite.\n" + "- Forecast range/count: Replace with candidate count, timebox, or tranche.\n" + "- Confidence: Replace with high, medium, or low and why.\n" + "- Throughput basis: Replace with recent completed sprint evidence or `not available`.\n" + "- Known unknowns: Replace with the main forecast risks.\n" + "- Scope hammers: Replace with operator-choice cut, defer, or reframe options.\n" + "- Expansion trigger: Replace with what requires operator decision or buy-more.\n\n" + "## Non-Goals\n\n1. Replace with the first non-goal.\n\n" + "## Status\n\nState: draft.\n\n" + "## Initiative Map\n\nNo initiatives yet.\n\n" + "## Retained Inputs\n\nNone yet.\n\n" + "## Transition And Reroute Rules\n\n1. Replace with transition or reroute rule.\n", + encoding="utf-8", + ) + print(wave_root.as_posix()) + return 0 + + +def command_create_initiative(args: argparse.Namespace) -> int: + wave_root = Path(args.wave_root).resolve() + wave_id_from_root(wave_root) + initiatives_root = wave_root / "initiatives" + initiatives_root.mkdir(parents=True, exist_ok=True) + number = ( + int(args.initiative_id[1:]) + if args.initiative_id + else next_number(initiatives_root, INIT_RE) + ) + initiative_id = f"i{number:02d}" + initiative_root = initiatives_root / f"{initiative_id}-{slugify(args.slug)}" + ensure_empty(initiative_root) + remove_gitkeep(initiatives_root) + replacements = { + "REPLACE_INITIATIVE_TITLE": args.slug.replace("-", " ").title(), + "REPLACE_APPETITE": "Replace with initiative appetite.", + "REPLACE_SUCCESS_EVIDENCE": "Replace with success evidence.", + "REPLACE_CIRCUIT_BREAKER": "Replace with circuit breaker.", + "REPLACE_DEFERRAL_PATH": "Replace with deferral path.", + } + copy_rendered_tree( + INITIATIVE_TEMPLATE_ROOT, initiative_root, replacements, skip_parts={"sprint-template"} + ) + add_gitkeep(initiative_root / "discoveries") + add_gitkeep(initiative_root / "sprints") + print((initiative_root / "initiative.md").as_posix()) + return 0 + + +def command_create_discovery(args: argparse.Namespace) -> int: + owner = Path(args.owner_root).resolve() + if (owner / "wave.md").exists(): + wave_root = owner + wave_id = wave_id_from_root(wave_root) + discoveries_root = wave_root / "discoveries" + number = next_number(discoveries_root, WAVE_DISCOVERY_RE) + filename = f"{wave_id}-d{number:02d}-{slugify(args.slug)}.md" + elif (owner / "initiative.md").exists(): + wave_root = owning_wave_root(owner) + wave_id = wave_id_from_root(wave_root) + initiative_id = initiative_id_from_root(owner) + discoveries_root = owner / "discoveries" + number = next_number(discoveries_root, INIT_DISCOVERY_RE) + filename = f"{wave_id}-{initiative_id}-d{number:02d}-{slugify(args.slug)}.md" + else: + raise ValueError("owner_root must be a wave root or initiative root") + discoveries_root.mkdir(parents=True, exist_ok=True) + path = discoveries_root / filename + if path.exists(): + raise ValueError(f"Discovery already exists: {path}") + remove_gitkeep(discoveries_root) + path.write_text( + f"# Discovery: {args.slug.replace('-', ' ').title()}\n\n" + "## Question\n\nReplace with the decision question.\n\n" + "## Context Receipt\n\nReplace with loaded artifacts and skipped surfaces.\n\n" + "## Repo Truth\n\nReplace with current repo truth.\n\n" + "## User Or Operator Evidence\n\n" + "- Status: Replace with `used`, `not triggered`, or `deferred`.\n" + "- Evidence: Replace with user/operator input, operator decision, or `n/a`.\n" + "- Decision impact: Replace with how the evidence changes this decision, or why it does not.\n\n" + "## Forecast Impact\n\n" + "- Status: Replace with `fits appetite`, `cuts/defers scope`, " + "`requires operator buy-more`, or `reroutes/stops`.\n" + "- Evidence: Replace with forecast basis or `n/a`.\n" + "- Decision impact: Replace with roadmap, index, or status update needed.\n\n" + "## Options\n\n- Recommended: Replace with recommended path.\n" + "- Rejected: Replace with rejected alternative.\n\n" + "## Recommendation\n\nReplace with recommendation.\n\n" + "## Validation Expectations\n\nReplace with validation expectations.\n\n" + "## Decision Slot\n\nPending operator decision.\n", + encoding="utf-8", + ) + print(path.as_posix()) + return 0 + + +def command_create_source_pack(args: argparse.Namespace) -> int: + owner = Path(args.owner_root).resolve() + if (owner / "wave.md").exists(): + packs_root = owner / "source-packs" + else: + packs_root = owner / "source-packs" if owner.name == ".ub-workflows" else owner + pack_date = args.date or datetime.now(tz=timezone.utc).date().isoformat() + if not re.fullmatch(r"\d{4}-\d{2}-\d{2}", pack_date): + raise ValueError("--date must use YYYY-MM-DD") + target = packs_root / f"{pack_date}-{slugify(args.slug)}" + ensure_empty(target) + remove_gitkeep(packs_root) + (target / "00-readme.md").write_text( + "---\n" + f"artifact_id : source-pack-{slugify(args.slug)}-readme\n" + "artifact_type : source_pack_readme\n" + "status : retained\n" + "context_tier : T3\n" + f"updated_at : {pack_date}\n" + "summary_budget_lines : 120\n" + "---\n\n" + f"# Source Pack: {args.slug.replace('-', ' ').title()}\n\n" + "## Status\n\nStatus: retained context.\n" + f"Date basis: {pack_date}.\n" + "Last reviewed: replace when reviewed.\n\n" + "## Context Routing\n\n" + "Read triggers: Replace with triggers.\n\n" + "Do not read for: startup, live state, or execution authorization.\n\n" + "Default section limit: open at most one named section file after this " + "readme unless the current artifact records a broader read receipt.\n\n" + "Promotion rule: facts become current truth only when promoted into the owning artifact.\n", + encoding="utf-8", + ) + print(target.as_posix()) + return 0 + + +def command_prepare_sprint(args: argparse.Namespace) -> int: + initiative_root = Path(args.initiative_root).resolve() + if not (initiative_root / "initiative.md").exists(): + raise ValueError("initiative_root must contain initiative.md") + wave_root = owning_wave_root(initiative_root) + wave_id = wave_id_from_root(wave_root) + initiative_id = initiative_id_from_root(initiative_root) + sprints_root = initiative_root / "sprints" + sprints_root.mkdir(parents=True, exist_ok=True) + if args.all: + candidates = [] + for line in (initiative_root / "roadmap.md").read_text(encoding="utf-8").splitlines(): + line_text = line.strip() + if line_text.startswith("- [ ]"): + candidate = line_text.removeprefix("- [ ]").strip() + if candidate.startswith("`") and candidate.endswith("`"): + candidate = candidate[1:-1].strip() + candidates.append(slugify(candidate)) + if not candidates: + candidates = [args.slug] + else: + candidates = [args.slug] + created: list[Path] = [] + for candidate in candidates: + number = next_number(sprints_root, SPRINT_RE) + candidate_slug = slugify(candidate) + sprint_slug = ( + candidate_slug if candidate_slug.startswith("sprint-") else f"sprint-{candidate_slug}" + ) + sprint_root = sprints_root / f"{wave_id}-{initiative_id}-s{number:02d}-{sprint_slug}" + ensure_empty(sprint_root) + remove_gitkeep(sprints_root) + sprint_id = f"{wave_id}-{initiative_id}-s{number:02d}" + today = datetime.now(tz=timezone.utc).date().isoformat() + replacements = { + "REPLACE_SPRINT_ARTIFACT_ID": sprint_root.name, + "REPLACE_DECISION_LOG_ARTIFACT_ID": f"{sprint_id}-decision-log", + "REPLACE_CLOSEOUT_ARTIFACT_ID": f"{sprint_id}-closeout", + "REPLACE_EVIDENCE_INDEX_ARTIFACT_ID": f"{sprint_id}-evidence-index", + "REPLACE_UPDATED_AT": today, + "REPLACE_SPRINT_TITLE": candidate.replace("-", " ").title(), + "REPLACE_SPRINT_OBJECTIVE": f"Deliver {candidate.replace('-', ' ')}.", + "REPLACE_SPRINT_SOURCE": "accepted discovery or reviewed preview pending", + "REPLACE_APPETITE": "Replace with sprint appetite.", + "REPLACE_SUCCESS_EVIDENCE": "Replace with success evidence.", + "REPLACE_CIRCUIT_BREAKER": "Replace with circuit breaker.", + "REPLACE_NON_GOALS": "Replace with non-goals.", + "REPLACE_DEFERRAL_PATH": "Replace with deferral path.", + } + copy_rendered_tree(SPRINT_TEMPLATE_ROOT, sprint_root, replacements) + created.append(sprint_root) + if not args.all: + break + for path in created: + print(path.as_posix()) + return 0 + + +def command_archive_initiative(args: argparse.Namespace) -> int: + initiative_root = Path(args.initiative_root).resolve() + wave_root = owning_wave_root(initiative_root) + archive_root = wave_root / "archive" / initiative_root.name + if archive_root.exists(): + raise ValueError(f"Archive target already exists: {archive_root}") + archive_root.parent.mkdir(parents=True, exist_ok=True) + shutil.move(initiative_root.as_posix(), archive_root.as_posix()) + refresh_gitkeep(initiative_root.parent) + print(archive_root.as_posix()) + return 0 + + +def generated_artifact_paths(workflow_root: Path) -> list[Path]: + candidates: list[Path] = [] + for name in ( + "wave.md", + "initiative.md", + "options.md", + "roadmap.md", + "index.md", + "retained-note.md", + ): + path = workflow_root / name + if path.exists(): + candidates.append(path) + for pattern in ( + "discoveries/*.md", + "sprints/*/sprint.md", + "sprints/*/decision-log.md", + "sprints/*/closeout.md", + "sprints/*/evidence/index.md", + ): + candidates.extend(sorted(workflow_root.glob(pattern))) + return candidates + + +def discover_generated_roots_for_placeholder_scan(scan_root: Path) -> list[Path]: + root = scan_root.resolve() + if (root / "initiative.md").exists() or (root / "wave.md").exists(): + return [root] + if root.name == "waves": + return sorted(path for path in root.iterdir() if path.is_dir() and WAVE_RE.match(path.name)) + if root.name == "initiatives": + return sorted(path for path in root.iterdir() if path.is_dir() and INIT_RE.match(path.name)) + if root.name == ".ub-workflows": + roots: list[Path] = [] + if (root / "waves").exists(): + for wave in sorted((root / "waves").glob("w??-*")): + roots.append(wave) + roots.extend(sorted((wave / "initiatives").glob("i??-*"))) + return [path for path in roots if path.is_dir()] + if (root / ".ub-workflows").exists(): + return discover_generated_roots_for_placeholder_scan(root / ".ub-workflows") + raise ValueError(f"Unsupported scan root: {scan_root}") + + +def collect_placeholder_findings(workflow_root: Path) -> list[PlaceholderFinding]: + findings: list[PlaceholderFinding] = [] + for path in generated_artifact_paths(workflow_root): + in_code_fence = False + for line_number, line in enumerate(path.read_text(encoding="utf-8").splitlines(), start=1): + if CODE_FENCE_RE.match(line): + in_code_fence = not in_code_fence + continue + if in_code_fence: + continue + findings.extend( + PlaceholderFinding( + workflow_root, + path, + line_number, + "machine-token", + "required", + marker, + line.strip(), + ) + for marker in MACHINE_PLACEHOLDER_RE.findall(line) + ) + if HUMAN_PLACEHOLDER_RE.search(line): + severity = ( + "advisory" if path.name in {"closeout.md", "retained-note.md"} else "required" + ) + findings.append( + PlaceholderFinding( + workflow_root, + path, + line_number, + "human-prompt", + severity, + "Replace with", + line.strip(), + ) + ) + if "PENDING_HANDOFF:" in line: + findings.append( + PlaceholderFinding( + workflow_root, + path, + line_number, + "pending-handoff", + "advisory", + "PENDING_HANDOFF:", + line.strip(), + ) + ) + return findings + + +def format_placeholder_summary(workflow_root: Path, findings: list[PlaceholderFinding]) -> str: + required = sum(1 for finding in findings if finding.severity == "required") + advisory = len(findings) - required + if not findings: + return f"placeholder summary: no unresolved generated-artifact placeholders under {workflow_root.as_posix()}" + lines = [ + f"placeholder summary: {required} required, {advisory} advisory finding(s) under {workflow_root.as_posix()}" + ] + for finding in findings: + try: + rel = finding.file_path.relative_to(workflow_root) + except ValueError: + rel = finding.file_path + lines.append( + f"- {finding.severity} {finding.category}: {rel.as_posix()}:{finding.line_number} -> {finding.marker}" + ) + return "\n".join(lines) + + +def collect_option_cards(path: Path) -> list[OptionCard]: + cards: list[OptionCard] = [] + lines = path.read_text(encoding="utf-8").splitlines() + current_title: str | None = None + current_line = 0 + current_fields: set[str] = set() + current_reviewed: date | None = None + + def finish_card() -> None: + nonlocal current_fields, current_line, current_reviewed, current_title + if current_title is None: + return + cards.append( + OptionCard( + file_path=path, + line_number=current_line, + title=current_title, + fields=frozenset(current_fields), + last_reviewed=current_reviewed, + ) + ) + current_title = None + current_line = 0 + current_fields = set() + current_reviewed = None + + for line_number, line in enumerate(lines, start=1): + match = OPTION_HEADING_RE.match(line) + if not match: + field_match = OPTION_FIELD_RE.match(line) + if current_title is not None and field_match: + current_fields.add(field_match.group("label").strip()) + date_match = OPTION_DATE_RE.match(line) + if current_title is not None and date_match: + current_reviewed = date.fromisoformat(date_match.group("date")) + continue + level = len(match.group("marks")) + if level == 2: + finish_card() + continue + finish_card() + current_title = match.group("title").strip() + current_line = line_number + finish_card() + return cards + + +def collect_option_board_findings( + workflow_root: Path, + path: Path, + *, + today: date, + stale_days: int, +) -> list[OptionsFinding]: + findings: list[OptionsFinding] = [] + if not path.exists(): + findings.append( + OptionsFinding( + workflow_root=workflow_root, + file_path=path, + line_number=None, + category="missing-options-board", + severity="required", + message=f"missing options board: {path.as_posix()}", + ) + ) + return findings + + lines = path.read_text(encoding="utf-8").splitlines() + for line_number, line in enumerate(lines, start=1): + match = OPTION_HEADING_RE.match(line) + if not match or len(match.group("marks")) != 2: + continue + normalized = match.group("title").strip().lower() + if normalized.startswith(FORBIDDEN_OPTION_LANE_PREFIXES): + findings.append( + OptionsFinding( + workflow_root=workflow_root, + file_path=path, + line_number=line_number, + category="forbidden-options-lane", + severity="required", + message=f"forbidden options-board archive lane: {match.group('title')}", + ) + ) + + for card in collect_option_cards(path): + missing_fields = sorted(REQUIRED_OPTION_FIELDS - card.fields) + findings.extend( + [ + OptionsFinding( + workflow_root=workflow_root, + file_path=card.file_path, + line_number=card.line_number, + category="missing-option-field", + severity="required", + message=f"option card `{card.title}` is missing `{field_name}`", + ) + for field_name in missing_fields + ] + ) + if card.last_reviewed is None: + continue + age_days = (today - card.last_reviewed).days + if age_days > stale_days: + findings.append( + OptionsFinding( + workflow_root=workflow_root, + file_path=card.file_path, + line_number=card.line_number, + category="stale-option-review", + severity="advisory", + message=( + f"option card `{card.title}` was last reviewed " + f"{age_days} day(s) ago" + ), + ) + ) + return findings + + +def options_review_routing_present(workflow_root: Path) -> bool: + for relative in ("AGENTS.md", "WORKFLOW_ATLAS.md", "status.md"): + path = workflow_root / relative + if not path.exists(): + continue + text = path.read_text(encoding="utf-8").lower() + if "options.md" in text and "transition" in text: + return True + return False + + +def collect_historical_backlog_findings(workflow_root: Path) -> list[OptionsFinding]: + findings: list[OptionsFinding] = [] + for path in sorted((workflow_root / "source-packs").glob("**/*.md")): + for line_number, line in enumerate(path.read_text(encoding="utf-8").splitlines(), start=1): + if "backlog" in line.lower() or "wishlist" in line.lower(): + findings.append( + OptionsFinding( + workflow_root=workflow_root, + file_path=path, + line_number=line_number, + category="historical-backlog-language", + severity="advisory", + message="retained source-pack wording mentions backlog or wishlist", + ) + ) + return findings + + +def collect_product_option_visibility_findings(workflow_root: Path) -> list[OptionsFinding]: + root_options = workflow_root / "options.md" + root_text = root_options.read_text(encoding="utf-8") if root_options.exists() else "" + initiative_root = active_initiative_root(workflow_root) + if initiative_root is None or not initiative_root.exists(): + return [] + + findings: list[OptionsFinding] = [] + for path in (initiative_root / "roadmap.md", initiative_root / "index.md"): + if not path.exists(): + continue + text = path.read_text(encoding="utf-8") + findings.extend( + [ + OptionsFinding( + workflow_root=workflow_root, + file_path=path, + line_number=None, + category="product-option-only-local", + severity="advisory", + message=f"product-level marker `{marker}` appears locally but not in root options", + ) + for marker in PRODUCT_OPTION_MARKERS + if marker in text and marker not in root_text + ] + ) + return findings + + +def collect_workflow_options_findings( + scan_root: Path, + *, + mode: str = "normal", + stale_days: int = 45, + include_history: bool = False, + today: date | None = None, +) -> list[OptionsFinding]: + workflow_root = discover_workflow_root(scan_root) + current_day = today or datetime.now(tz=timezone.utc).date() + findings: list[OptionsFinding] = [] + + root_options = workflow_root / "options.md" + if not root_options.exists(): + findings.append( + OptionsFinding( + workflow_root=workflow_root, + file_path=root_options, + line_number=None, + category="missing-root-options", + severity="required", + message="missing root options board", + ) + ) + + initiative_root = active_initiative_root(workflow_root) + if initiative_root is not None: + initiative_options = initiative_root / "options.md" + if not initiative_options.exists(): + findings.append( + OptionsFinding( + workflow_root=workflow_root, + file_path=initiative_options, + line_number=None, + category="missing-initiative-options", + severity="required", + message="active initiative is missing local options board", + ) + ) + + roadmap = active_initiative_roadmap(workflow_root) + if roadmap and roadmap.exists() and "## Later Candidate Queue" in roadmap.read_text( + encoding="utf-8" + ): + findings.append( + OptionsFinding( + workflow_root=workflow_root, + file_path=roadmap, + line_number=None, + category="later-candidate-queue", + severity="required", + message="active roadmap contains `## Later Candidate Queue`", + ) + ) + + for path in option_board_paths(workflow_root, include_history=include_history): + findings.extend( + collect_option_board_findings( + workflow_root, + path, + today=current_day, + stale_days=stale_days, + ) + ) + + if mode in {"transition", "terminal-audit"} and not options_review_routing_present( + workflow_root + ): + findings.append( + OptionsFinding( + workflow_root=workflow_root, + file_path=workflow_root / "AGENTS.md", + line_number=None, + category="missing-transition-routing", + severity="required", + message="transition mode requires root options review routing", + ) + ) + + if mode in {"closeout", "terminal-audit"} and initiative_root is not None: + initiative_options = initiative_root / "options.md" + if initiative_options.exists(): + findings.extend( + [ + OptionsFinding( + workflow_root=workflow_root, + file_path=card.file_path, + line_number=card.line_number, + category="unresolved-local-option", + severity="required", + message=f"local option `{card.title}` remains unresolved for {mode}", + ) + for card in collect_option_cards(initiative_options) + ] + ) + + findings.extend(collect_product_option_visibility_findings(workflow_root)) + findings.extend(collect_historical_backlog_findings(workflow_root)) + return findings + + +def format_options_summary(workflow_root: Path, findings: list[OptionsFinding]) -> str: + required = sum(1 for finding in findings if finding.severity == "required") + advisory = len(findings) - required + if not findings: + return ( + "options summary: no options-board findings under " + f"{workflow_root.as_posix()}" + ) + lines = [ + "options summary: " + f"{required} required, {advisory} advisory finding(s) under " + f"{workflow_root.as_posix()}" + ] + for finding in findings: + try: + rel = finding.file_path.relative_to(workflow_root) + except ValueError: + rel = finding.file_path + suffix = "" if finding.line_number is None else f":{finding.line_number}" + lines.append( + f"- {finding.severity} {finding.category}: " + f"{rel.as_posix()}{suffix} -> {finding.message}" + ) + return "\n".join(lines) + + +def build_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser(description=__doc__) + subparsers = parser.add_subparsers(dest="command", required=True) + + bootstrap = subparsers.add_parser("bootstrap") + bootstrap.add_argument("--ops-root", default=str(DEFAULT_OPS_ROOT)) + + wave = subparsers.add_parser("create-wave") + wave.add_argument("wave_id") + wave.add_argument("slug") + wave.add_argument("--ops-root", default=str(DEFAULT_OPS_ROOT)) + + initiative = subparsers.add_parser("create-initiative") + initiative.add_argument("wave_root") + initiative.add_argument("slug") + initiative.add_argument("--initiative-id") + + discovery = subparsers.add_parser("create-discovery") + discovery.add_argument("owner_root") + discovery.add_argument("slug") + + source_pack = subparsers.add_parser("create-source-pack") + source_pack.add_argument("owner_root") + source_pack.add_argument("slug") + source_pack.add_argument("--date") + + sprint = subparsers.add_parser("prepare-sprint") + sprint.add_argument("initiative_root") + sprint.add_argument("slug") + sprint.add_argument("--all", action="store_true") + + archive = subparsers.add_parser("archive-initiative") + archive.add_argument("initiative_root") + return parser + + +def main() -> int: + args = build_parser().parse_args() + match args.command: + case "bootstrap": + return command_bootstrap(args) + case "create-wave": + return command_create_wave(args) + case "create-initiative": + return command_create_initiative(args) + case "create-discovery": + return command_create_discovery(args) + case "create-source-pack": + return command_create_source_pack(args) + case "prepare-sprint": + return command_prepare_sprint(args) + case "archive-initiative": + return command_archive_initiative(args) + raise AssertionError(args.command) + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/.gitignore b/.gitignore index c99767c..e8ddbaa 100644 --- a/.gitignore +++ b/.gitignore @@ -14,9 +14,9 @@ __pycache__/ .pytest_cache/ .ruff_cache/ -# Local tmp scratch +# Local scratch and workflow state /tmp -/.ub-workflows/** +/.ub-workflows/ # Node/VitePress artifacts /dist diff --git a/.ub-workflows/archive/.gitkeep b/.ub-workflows/archive/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/AGENTS.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/AGENTS.md deleted file mode 100644 index 9c4c617..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/AGENTS.md +++ /dev/null @@ -1,32 +0,0 @@ -# Initiative Root — AGENTS.md - -## Scope - -Applies to this initiative root and its descendants. - -## Local Rules - -- `roadmap.md` is the smallest live progress document for the initiative. -- Read `roadmap.md` first when resuming work. -- Treat each sprint's `sprint.md` as a standalone sprint PRD. -- Do not assume the master `prd.md` must be open to execute a sprint. -- Treat `roadmap.md` as the durable planning artifact after PRD work is done. -- Keep sprint execution sequential unless the roadmap explicitly says otherwise. -- End the roadmap with a mandatory final audit step. - -## Resume Order - -1. `./roadmap.md` -2. the latest sprint `closeout.md` -3. the active or next sprint `sprint.md` -4. `./README.md` -5. `./prd.md` only if needed for additional initiative-level context - -## Update Discipline - -- Update `roadmap.md` after every meaningful sprint state change. -- Update `README.md` when blockers, phase, or next step changes. -- Keep the active sprint's `closeout.md` current before stopping work. -- Do not create sprint folders until `roadmap_ready: pass`. -- Create sprint folders from `./sprint-template/` only when initializing the approved roadmap. -- Record the user's follow-up audit or refactor decision before closing the initiative. diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/README.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/README.md deleted file mode 100644 index 635f9d3..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# Initiative Status - -## Snapshot - -- Initiative: Repository Self-Governance Hardening -- Owner: robert-hoffmann -- Imported on: 2026-04-16 -- Governance bridge: `Level 1` -- Governance profile: `lean` -- Current phase: Final audit complete, awaiting archive review -- Current gate: `archive_ready: pass` -- Roadmap status: `complete` -- Active sprint: `none` -- Last completed sprint: `Final Audit - Repository Hardening Final Audit` -- Next step: Review `./sprints/11-final-audit/closeout.md` and `./retained-note.md`, then archive only on explicit human approval -- Blockers: `none` - -## Resume Here - -1. Read `./roadmap.md`. -2. Read `./sprints/11-final-audit/closeout.md`. -3. Read `./retained-note.md`. -4. Read `./README.md` if you need the root summary. -5. Archive only when you explicitly decide to do so. - -## Validation Pointers - -- Validation baseline: Final audit reconfirmed the full repository baseline through `task check`, strict generated-output placeholder validation, and archive dry-run readiness. -- Documentation sync status: `README.md`, `roadmap.md`, and `retained-note.md` now reflect the same completion and archive-review state. -- Exception records: `none` diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/exceptions/.gitkeep b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/exceptions/.gitkeep deleted file mode 100644 index 2fa992c..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/exceptions/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -keep diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/exceptions/AGENTS.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/exceptions/AGENTS.md deleted file mode 100644 index 0f94147..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/exceptions/AGENTS.md +++ /dev/null @@ -1,12 +0,0 @@ -# Exceptions — AGENTS.md - -## Scope - -Applies to the `exceptions/` directory inside one initiative root. - -## Local Rules - -- Record only explicit, bounded exceptions here. -- Every exception note should name the owner, expiration condition, and the - affected workflow gate. -- Remove stale exception records during sprint closeout or final audit. diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/exceptions/exception-template.yaml b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/exceptions/exception-template.yaml deleted file mode 100644 index 483a8b5..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/exceptions/exception-template.yaml +++ /dev/null @@ -1,9 +0,0 @@ -# Copy this file to a dated name such as YYYY-MM-DD-governance-exception.yaml -# when a governed initiative needs a bounded exception record. - -governance_exception: - owner: "@team-or-person" - rationale: "Why the baseline policy cannot be applied right now" - created_at: "YYYY-MM-DD" - expires_at: "YYYY-MM-DD" - follow_up: "https://tracker.example.com/ISSUE-123" diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/prd.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/prd.md deleted file mode 100644 index a533140..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/prd.md +++ /dev/null @@ -1,1040 +0,0 @@ -# Repository Self-Governance Hardening PRD - -> This document is the complete standalone product and execution specification for hardening the Uncle Bob / itech-agents repository so that its inventories, documentation, metadata, packaging conventions, workflow assets, and maintenance expectations stay aligned over time. - -Date: 2026-04-15 -Project name in repository metadata: `uncle-bob` -Local repository inspected for this revision: `/Users/itechnology/Dev/itech-agents` -Primary repository URL: `https://github.com/robert-hoffmann/uncle-bob` -Status: revised after repository truth check and consolidation of prior analysis notes - ---- - -## 1. Executive summary - -This repository is already much stronger than a typical skill collection. It has real architecture, layered responsibilities, executable support in key areas, and a meaningful distinction between core policy and specialized skills. - -Its strongest traits are: - -- a layered instruction model centered on `AGENTS.md`, `ub-quality`, and sibling specialization -- strong separation of concerns across skills -- progressive disclosure through references instead of one giant instruction blob -- real operational tooling in `ub-governance` and `ub-workflow` -- actual tests for some critical paths rather than purely aspirational quality claims - -The repository’s main weakness is not conceptual quality. The main weakness is that the maintenance automation has not caught up with the architecture. - -The repository still depends on manual consistency across several public surfaces: - -- on-disk skills -- on-disk agent definitions -- root registry guidance -- README tables and install instructions -- plugin metadata -- marketplace metadata -- skill-local references and support assets -- workflow scaffolding assets and tests - -Since the earlier analysis, the repository has already moved forward in meaningful ways: - -- `ub-initiative-flow` has been renamed to `ub-workflow` -- the README has already been updated to refer to `ub-workflow` -- the Taskfile has already been updated to point workflow tests at `ub-workflow` - -That means this initiative should not be framed as migration cleanup anymore. The migration is largely done. The actual need now is a durable repository-wide self-governance layer that prevents the next round of drift. - -This PRD therefore focuses on four practical outcomes: - -1. derive repository truth from canonical tracked files and on-disk assets -2. validate public descriptive surfaces against that truth -3. keep checks precise and low-noise by validating only authoritative surfaces by default -4. define enough schema and packaging policy to reduce accidental drift without turning governance into ceremony - -The recommended first implementation slice is intentionally narrow: - -- repository catalog integrity checking -- exact path and case validation -- metadata consistency checking across README and plugin surfaces -- validation of skill reference paths and basic structural contracts -- local and CI parity for those checks - -Broader ideas such as freshness and maturity remain useful, but they are secondary to getting a reliable integrity baseline in place. - ---- - -## 2. Problem statement - -The repository’s core problem is not weak content. It is weak enforcement of repository truth. - -The repository is now large and structured enough that manual synchronization is an operational liability. The likely future failure mode is not one dramatic breakage. It is gradual trust erosion caused by silent drift. - -Observed categories of risk include: - -1. Inventory drift risk - - skills and agents are described in multiple places - - there is no repository-wide validator keeping those surfaces aligned - -2. Documentation and metadata drift - - README, root registry guidance, plugin metadata, and marketplace metadata can silently diverge from actual repository contents - -3. Rename and deprecation drift - - `ub-initiative-flow` has already been migrated to `ub-workflow` - - future renames can leave stale references behind if not validated automatically - -4. Path and case drift - - `AGENTS.md` is the intended canonical root registry standard - - exact path and case validation is required because legacy casing and copied references create avoidable portability bugs - -5. Validation scope ambiguity - - the repository contains temporary/test-oriented content under `tmp/` - - integrity tooling that scans too broadly will generate noise and become untrusted - -6. Duplication-driven drift - - consistency across many skills appears to be maintained partly by copied boilerplate rather than strongly enforced shared contracts - - repeated mistakes can propagate widely when copied - -7. Uneven hardening - - `ub-governance` already includes focused integrity and regression checks - - `ub-workflow` already includes scripts, assets, and tests - - many language/framework skills still rely mostly on prose quality and manual upkeep - -8. Under-specified metadata and packaging conventions - - not all packaging expectations are explicit - - maintainers and contributors cannot always tell what “complete” packaging means for a skill - - tooling cannot safely depend on loosely implied metadata conventions - -9. Volatile guidance risk - - framework and tooling guidance for Nuxt, Vue, Tailwind, Python, TypeScript, and Copilot customization can age quickly - - the repository does not yet have an explicit freshness discipline for that volatility - -10. Portability and rigidity risk - -- some guidance, especially in core-quality surfaces, may be too rigid for broad reuse across diverse downstream repos -- without clearer contracts, “quality baseline” can slide into “one preferred style for everything” - -In short: the repository has outgrown informal maintenance. - ---- - -## 3. Why this matters - -If this is left alone, the likely outcomes are: - -- a skill gets added on disk but not listed in the registry or README -- a removed or renamed skill remains referenced in canonical docs -- plugin or marketplace metadata continues to sound authoritative while no longer matching reality -- install instructions point to paths or filenames that are wrong -- a skill’s `Load References On Demand` paths drift and no one notices until runtime use -- duplicated boilerplate slowly diverges in meaning across skills -- a checker is eventually added but scans too broadly, flags temporary content, and becomes noisy enough to ignore - -This matters because the repository is not just documentation. It is operational instruction infrastructure for downstream agent behavior. If it cannot describe itself accurately, people will stop trusting it — gradually, quietly, and correctly. - -Self-governance hardening turns silent drift into early visible failure. - ---- - -## 4. Product vision - -Create a repository that is: - -1. Authoritative - - repository truth is derived from canonical tracked files and on-disk assets - -2. Self-validating - - local checks and CI catch inventory drift, stale references, path/case mistakes, metadata mismatches, reference-path breakage, and scaffold issues before they spread - -3. Explicitly scoped - - integrity tooling validates only authoritative repository surfaces by default and ignores temporary or fixture content unless explicitly asked to scan them - -4. Contributor-friendly - - maintainers can add, rename, package, or remove skills and agents without guessing which public surfaces also need updating - -5. Evolution-safe - - fast-moving framework guidance can be reviewed and updated without destabilizing the rest of the repository - -6. Portable enough to travel - - the repository can maintain strong defaults without pretending every downstream repo must share identical stylistic or tooling preferences - ---- - -## 5. Goals - -### Primary goals - -1. Eliminate drift between on-disk repository inventory and published metadata/documentation surfaces. -2. Add precise repository-wide integrity checks that run both locally and in CI. -3. Define explicit authoritative surfaces and explicit non-authoritative surfaces. -4. Reduce path, case, and reference drift. -5. Validate skill reference paths and basic structural contracts. -6. Improve scaffold completeness visibility for `ub-workflow`. -7. Clarify packaging expectations for skills and agents. - -### Secondary goals - -1. Introduce advisory freshness discipline for volatile guidance. -2. Add maturity or packaging-tier signaling only if it improves real maintenance and review decisions. -3. Reduce duplication-driven drift where practical. -4. Make the repository safer to reuse across projects with different local conventions. - ---- - -## 6. Non-goals - -This initiative is not intended to: - -- rewrite the philosophy of the repository -- rewrite every skill for stylistic consistency -- generate all documentation from a master manifest in phase 1 -- semantically parse arbitrary markdown prose beyond defined structured sections -- validate temporary, fixture, or generated content as authoritative metadata by default -- preserve transitional documented artifacts forever -- force a maturity-label system in phase 1 if it does not yet drive decisions -- remove strong quality opinions entirely just to appear more generic - ---- - -## 7. Users and stakeholders - -### Primary stakeholders - -1. Repository maintainer - - needs dependable low-noise checks and clear failure messages - -2. Future contributors - - need to know what files are authoritative, what references must resolve, and what “complete packaging” means - -3. Downstream users of the repo - - need to trust that README, root registry guidance, metadata, and workflow assets match reality - -### Secondary stakeholders - -1. Users consuming workflow scaffolds from `ub-workflow` -2. Anyone relying on plugin/marketplace metadata to understand what the repository contains -3. Teams adopting only parts of the repo and needing clarity about what is essential versus optional - ---- - -## 8. Current-state diagnosis - -### 8.1 The repository is materially stronger than before - -As of this revision: - -- `ub-initiative-flow` has been replaced by `ub-workflow` -- `ub-workflow` exists on disk as a real skill -- `ub-workflow` has a corresponding on-disk agent definition -- the README already reflects `ub-workflow` -- the Taskfile already points workflow tests at `ub-workflow` - -This means the repository has already corrected one major class of earlier drift. - -### 8.2 The repository still lacks a unified integrity layer - -The repository still depends on manual maintenance across: - -- `.agents/skills/*/SKILL.md` -- `.github/agents/*.agent.md` -- `AGENTS.md` as the intended root registry standard -- `README.md` -- `plugin.json` -- `.github/plugin/marketplace.json` -- skill-local references and support assets - -Those surfaces are not yet governed by one repository-level integrity system. - -### 8.3 Strong engineering exists, but only in parts of the repo - -The earlier analysis was right to highlight that the repository is strongest where it treats skills like products rather than prose. - -That is still true now, just with updated naming: - -- `ub-governance` is an engineered subsystem with checks, schemas, and regression tests -- `ub-workflow` is an engineered workflow product with templates, scripts, and tests - -This is good news, not bad news. It means the repo already contains working patterns for how hardening should look. The gap is that those patterns are not yet elevated to a repository-wide maintenance model. - -### 8.4 Transitional artifacts must be handled explicitly - -At the time of this revision, `Explore` is still documented as an agent concept, but it is intended to be removed. The repository hardening design must support temporary explicit ignores for this kind of transitional item instead of treating it as either permanent truth or accidental mismatch. - -### 8.5 Low-noise validation is a requirement, not a nicety - -The repository contains temporary/test-oriented paths such as `tmp/`. Any integrity system that treats every markdown-like surface as authoritative will quickly become noisy and stop being trusted. - -### 8.6 Duplication is a structural risk multiplier - -The deeper notes were correct that consistency here is partly achieved by duplication rather than reuse. - -That does not make the repository weak, but it does create a specific maintenance hazard: - -- repeated wording changes can drift in meaning -- repeated path references can drift in casing -- repeated packaging conventions can diverge silently -- the same bug can spread across multiple skills through copy/paste - -This initiative should therefore reduce duplication-driven risk through validation and clearer contracts, not just more prose. - ---- - -## 9. Core principles for this initiative - -1. Disk truth first - - use tracked on-disk assets and canonical tracked files as the baseline truth - -2. Validate descriptive surfaces against that truth - - do not rely on descriptive docs as the only inventory source - -3. Keep phase 1 practical - - catch high-value drift first before adding broad policy layers - -4. Precision over breadth - - false positives are a governance failure - -5. Explicit exceptions over silent ambiguity - - if something is temporarily ignored, that should be declared intentionally - -6. Exact path and case correctness matter - - canonical names should be enforced deliberately, not implied loosely - -7. Validate actual runtime-facing references - - if a skill tells the agent to load a reference file, that path should resolve - -8. Build on existing hardening - - reuse and extend the governance and workflow foundations already present in the repository - -9. Prefer contracts over duplicated folklore - - when many skills repeat the same expectations, validate the contract instead of trusting repetition - -10. Preserve portability where possible - -- the repository can stay opinionated without assuming all downstream repos share one exact style stack or enforcement posture - ---- - -## 10. Proposed solution overview - -This initiative should be delivered in two layers. - -### Layer 1: Core repository integrity - -A. Repository catalog integrity checker -B. Agent and metadata consistency checker -C. Exact path and case validator -D. Skill reference-path and minimal schema validator -E. Local and CI parity for all core checks - -### Layer 2: Hardening extensions - -F. `ub-workflow` scaffold completeness validator -G. Packaging policy and optional tier signaling -H. Advisory freshness policy for volatile references -I. Selective refactoring of high-duplication shared conventions where validation alone is insufficient - -The recommendation is to ship Layer 1 first. - ---- - -## 11. Detailed product requirements - -## 11.1 Repository catalog integrity checker - -### Requirement - -The repository must have a canonical integrity checker that derives baseline inventory from tracked on-disk skills and validates structured public surfaces against that baseline. - -### Proposed file - -- `.agents/skills/ub-governance/scripts/check_repo_catalog.py` - -### Canonical inputs - -- `.agents/skills/*/SKILL.md` -- `.github/agents/*.agent.md` -- root `AGENTS.md` -- `README.md` -- `plugin.json` -- `.github/plugin/marketplace.json` - -### Default ignore scope - -The checker must ignore the following by default unless explicitly configured otherwise: - -- `tmp/` -- fixtures -- generated outputs -- examples not declared as canonical surfaces - -### Functional behavior - -The checker must: - -1. discover all skills from `.agents/skills/*/SKILL.md` -2. discover all agent definitions from `.github/agents/*.agent.md` -3. parse the canonical skills and agents listed in the root `AGENTS.md` registry tables -4. parse the structured skill and agent tables in `README.md` -5. validate relevant inventory and count claims in `plugin.json` and `.github/plugin/marketplace.json` -6. report mismatches with file and line detail when possible -7. exit non-zero on real violations -8. support an explicit temporary ignore list for transitional entries such as `Explore` - -### Example failures it should catch - -- a skill exists on disk but is missing from `AGENTS.md` -- a skill is listed in `README.md` but does not exist on disk -- a renamed skill such as `ub-initiative-flow` is still referenced in a canonical surface -- marketplace metadata claims a count that does not match tracked assets -- an agent is documented but not present on disk and not listed in the explicit transitional ignore set - -### Example output - -```text -ERROR: Skill present on disk but missing from AGENTS.md: ub-workflow -ERROR: README.md references removed skill name: ub-initiative-flow -ERROR: Marketplace metadata claims 5 agents, but 4 tracked .agent.md files exist -WARNING: Transitional agent entry ignored by policy: Explore -``` - ---- - -## 11.2 Minimal skill schema and reference validator - -### Requirement - -Every skill must comply with a practical structural contract, and every canonical runtime-facing reference path in a skill must resolve. - -### Proposed files - -- `.agents/skills/ub-governance/references/skill-frontmatter.schema.json` -- `.agents/skills/ub-governance/scripts/check_skill_schema.py` - -### Phase-1 contract - -Each `SKILL.md` must contain: - -- YAML frontmatter -- `name` -- `description` -- frontmatter `name` matching the parent directory name -- readable UTF-8 content - -The validator should also confirm that canonical referenced relative paths in the skill actually exist, especially in patterns such as: - -- `Read \`references/...\`` -- `Read \`docs/...\`` -- `Use \`scripts/...\`` -- other explicit path-style guidance that the agent is expected to follow at runtime - -### Why this matters - -The deeper notes correctly identified that repository integrity is not just about top-level inventory. It is also about whether the repository’s own usage instructions resolve to real assets. - -### Deferred contract ideas - -The following may be added later if they prove useful and low-noise: - -- stricter required section taxonomy -- support asset conventions by skill type -- volatility metadata -- maturity metadata - -### Rationale - -Start with structural correctness and reference validity, not ceremonial prose policing. - ---- - -## 11.3 Agent and package metadata validator - -### Requirement - -The repository must validate that package and marketplace metadata still describe the real repository contents accurately. - -### Proposed file - -- `.agents/skills/ub-governance/scripts/check_package_metadata.py` - -### Functional behavior - -The validator must: - -1. compare declared counts and inventory-like claims against tracked skill and agent files -2. validate that referenced repository paths exist and use canonical casing -3. report stale references to removed or renamed skills/agents -4. respect the explicit transitional ignore list for items intentionally pending removal - -### Example failures it should catch - -- `.github/plugin/marketplace.json` claims five agents when only four tracked agent files exist and the fifth is merely a temporary documented artifact -- package metadata describes workflow assets using a stale renamed skill path - ---- - -## 11.4 Path and case validator - -### Requirement - -The repository must validate exact path and case correctness for canonical repository surfaces. - -### Proposed file - -- `.agents/skills/ub-governance/scripts/check_repo_paths.py` - -### Canonical rule - -The intended root registry standard is `AGENTS.md`, and repository guidance should converge on that exact path and casing. - -### Functional behavior - -The validator must: - -1. build a canonical tracked path index from git -2. extract path-like references from canonical surfaces only -3. validate exact path existence and exact casing against tracked paths -4. report line-level mismatches when possible -5. ignore non-authoritative surfaces by default - -### Example failures it should catch - -- `AGENTS.MD` referenced where `AGENTS.md` is the intended standard -- `skill.md` referenced where `SKILL.md` is the tracked canonical file -- stale path references under renamed workflow surfaces - -### Important constraint - -Do not attempt speculative path extraction from arbitrary prose. Validate explicit path-like references and structured sections only. - ---- - -## 11.5 ub-workflow scaffold completeness validation - -### Requirement - -`ub-workflow` scaffold generation must make unresolved placeholders visible and optionally fail in strict mode. - -### Proposed files - -- `.agents/skills/ub-workflow/scripts/check_scaffold_placeholders.py` -- update `.agents/skills/ub-workflow/scripts/scaffold_initiative.py` -- tests under `.agents/skills/ub-workflow/tests/` - -### Functional behavior - -After scaffold generation, the tooling must: - -1. scan generated initiative output for unresolved placeholder tokens -2. classify unresolved placeholders as required or optional -3. print a deterministic unresolved placeholder summary -4. optionally fail in strict mode when required placeholders remain - -### Important scope rule - -Placeholder checks apply to generated initiative artifacts, not to canonical template files by default. - -### Why this matters - -The deeper notes correctly observed that scaffold generation is safe against clobbering but not strict enough about completeness. That is a real quality gap worth closing. - -### Example output - -```text -Scaffold created at ./.ub-workflows/initiatives/2026-04-15-example -Unresolved placeholders: -- REPLACE_OWNER (optional) -- REPLACE_VALIDATION_COMMANDS (optional) -``` - -### Strict-mode failure example - -```text -ERROR: Required placeholder still unresolved after scaffold render: REPLACE_INITIATIVE_NAME -``` - ---- - -## 11.6 Packaging policy and optional tier signaling - -### Requirement - -The repository should define what “complete packaging” means for a skill and whether that packaging level is visible. - -### Problem being solved - -The deeper notes were right that packaging expectations are currently under-specified: - -- some skills have agents -- some have scripts/tests/assets/docs -- some are intentionally prose-first -- but the repository does not make the distinction explicit enough for contributors or tooling - -### Proposed deliverable - -- `docs/skill-schema.md` or equivalent canonical packaging-policy document - -### Minimum policy questions to answer - -1. Which skill assets are always required? -2. Which are optional? -3. When should a skill include `agents/`? -4. When should a skill include `scripts/` and `tests/`? -5. Which metadata fields are safe for tools to depend on? - -### Optional tier model - -If useful, the repo may use lightweight packaging tiers such as: - -- Base: `SKILL.md` plus required references -- Operational: Base plus scripts/tests/assets/docs as needed - -### Constraint - -Do not make this phase-1 mandatory unless it directly improves contributor behavior or automation quality. - ---- - -## 11.7 Freshness discipline for volatile references - -### Requirement - -Fast-moving framework guidance should have an advisory freshness policy. - -### Candidate high-volatility areas - -- Tailwind -- Nuxt -- Vue -- TypeScript -- Python ecosystem tooling recommendations -- Copilot customization behavior and vendor-specific conventions - -### Suggested metadata - -This may live either in frontmatter or adjacent review metadata: - -```yaml -volatility: high -reviewed_at: 2026-04-15 -review_cycle: quarterly -``` - -### Policy - -- freshness should be warning-first, not blocking by default -- stable principles should be distinguishable from volatile setup recipes -- review timestamps should help prioritization, not become performative bureaucracy - -### Additional caution - -The deeper notes correctly pointed out that “latest stable” is philosophically right but operationally underdefined. The freshness layer should therefore guide review rather than pretend to eliminate judgment. - ---- - -## 11.8 Portability guardrails for core quality surfaces - -### Requirement - -Core repository guidance should remain strong, but it should be explicit about what is mandatory repository policy versus what is recommended house style. - -### Problem being solved - -The deeper notes raised a fair concern that `ub-quality` may be too rigid to scale cleanly across diverse downstream repos if every opinion is treated as universally binding. - -### Proposed outcome - -This initiative should not weaken the repository’s standards, but it should clarify: - -- which constraints are fundamental repository policy -- which constraints are style defaults -- which constraints may need explicit downstream opt-out or adaptation - -### Why this matters - -This improves portability without gutting the repository’s identity. - ---- - -## 12. User stories - -### Maintainer stories - -1. As a maintainer, when I add or remove a skill, CI should tell me exactly which canonical surfaces are out of sync. -2. As a maintainer, when I rename a workflow skill or agent, stale references should fail quickly. -3. As a maintainer, when I document a transitional item like `Explore`, I want that exception to be explicit rather than silent. -4. As a maintainer, I want integrity tooling to ignore temporary content by default so I can trust its output. -5. As a maintainer, I want runtime-facing skill references validated so I know instructions are actually usable. -6. As a maintainer, I want clearer packaging expectations so contributors do not have to reverse-engineer the repository’s conventions. - -### Contributor stories - -1. As a contributor, I want a clear definition of authoritative files so I know what must stay aligned. -2. As a contributor, I want local checks and CI to agree. -3. As a contributor using `ub-workflow`, I want unresolved placeholders to be obvious immediately. -4. As a contributor creating a new skill, I want to know what metadata and support assets are expected. - -### Consumer stories - -1. As a downstream user, I want to trust that the repository’s skill and agent descriptions match the actual repository. -2. As a downstream user, I want setup guidance to point at the right canonical filenames and paths. -3. As a downstream user, I want to understand whether a skill is prose-only guidance or a more operationally hardened subsystem. - ---- - -## 13. Scope - -## In scope - -- repository-wide inventory checks across on-disk skills, on-disk agents, `AGENTS.md`, `README.md`, `plugin.json`, and `.github/plugin/marketplace.json` -- exact tracked path and case validation for canonical repository surfaces -- explicit temporary ignore handling for transitional entries such as `Explore` -- low-noise structured parsing of tables and explicit path references -- local Taskfile and CI parity for core integrity checks -- `ub-workflow` scaffold placeholder visibility and strict-mode support -- minimal skill schema and reference-path validation -- packaging-policy clarification -- advisory freshness design -- clearer distinction between mandatory policy and more opinionated defaults where needed for portability - -## Out of scope - -- full generation of docs from a central manifest in phase 1 -- semantic parsing of arbitrary README prose -- immediate deep test retrofits for every skill -- forced maturity labeling across all skills before it is useful -- treating `tmp/` or other temporary content as authoritative repository truth by default -- removing strong repository opinions just to maximize generic reuse - ---- - -## 14. Success metrics - -### Leading indicators - -1. Zero mismatches between on-disk skill inventory and structured registry surfaces. -2. Zero mismatches between on-disk agent inventory and structured metadata surfaces, excluding explicit transitional ignores. -3. Zero canonical path/case mismatches in validated repository surfaces. -4. Zero broken canonical runtime-facing reference paths in validated skills. -5. Zero false positives from temporary or fixture content in default integrity-check mode. -6. Local Taskfile checks and CI run the same integrity suite. -7. `ub-workflow` scaffold checks report unresolved placeholders deterministically. - -### Lagging indicators - -1. future skill/agent renames are caught automatically when docs lag behind -2. repository metadata remains trustworthy after multiple iterative updates -3. contributors do not need informal tribal knowledge to keep repository surfaces aligned -4. consumers can better distinguish between lightly packaged and operationally hardened skills - ---- - -## 15. Risks and mitigations - -### Risk 1: Checker noise kills trust - -Mitigation: - -- validate only canonical surfaces by default -- keep explicit ignore lists small and reviewable -- prefer precise failures over broad heuristics - -### Risk 2: Scope expands too early - -Mitigation: - -- ship core integrity first -- defer broader policy layers until the baseline is solid - -### Risk 3: Freshness metadata becomes theater - -Mitigation: - -- keep freshness advisory initially -- separate stable principles from volatile recipes - -### Risk 4: Transitional exceptions become permanent clutter - -Mitigation: - -- require explicit ignore entries for temporary exceptions -- review and remove them deliberately - -### Risk 5: Canonical filename migration creates temporary inconsistency - -Mitigation: - -- standardize future guidance on `AGENTS.md` -- let path/case validation make any residual legacy casing visible - -### Risk 6: Packaging policy becomes bureaucratic - -Mitigation: - -- keep packaging policy minimal and decision-oriented -- define only what contributors and tooling actually need - -### Risk 7: Portability concerns get ignored because the repo is internally coherent - -Mitigation: - -- explicitly distinguish non-negotiable repository policy from more opinionated defaults -- preserve strong standards without pretending every downstream repo must use the exact same enforcement posture - ---- - -## 16. Dependencies and assumptions - -This PRD assumes: - -- the repository will continue using `.agents/skills/` and `.github/agents/` as canonical asset roots -- the intended root registry filename standard is `AGENTS.md` -- `ub-workflow` is the canonical successor to `ub-initiative-flow` -- existing governance scripts under `ub-governance` are the best place to host repository-wide integrity tooling initially -- `Explore` is temporary and intended for removal, not a permanent on-disk agent requirement -- skill-local path references are part of real repository behavior and should be validated as such - ---- - -## 17. Rollout plan - -## Phase 0: truth alignment and scope definition - -1. declare canonical repository surfaces in writing -2. declare default ignored surfaces in writing -3. declare the temporary ignore treatment for `Explore` -4. converge future documentation and planning on `AGENTS.md` - -## Phase 1: repository integrity baseline - -1. implement repository catalog checker -2. implement package/marketplace metadata checker -3. implement exact path/case validator -4. wire all three into local developer workflow and CI - -## Phase 2: structural hardening - -1. implement minimal skill schema validation -2. validate canonical skill reference paths -3. add targeted test coverage for new checks - -## Phase 3: workflow hardening - -1. add `ub-workflow` generated-output placeholder validator -2. add strict-mode support where useful -3. ensure deterministic test coverage for scaffold validation - -## Phase 4: policy clarification - -1. define minimal packaging policy for skills and agents -2. clarify portability boundaries for core-quality guidance -3. add freshness review metadata only if maintainers still want it -4. add optional tier signaling only if it solves a real problem - ---- - -## 18. Maintainer action list with examples - -## Action 1: create the repository catalog checker - -Deliverables: - -- enumerate skills from `.agents/skills/*/SKILL.md` -- enumerate agents from `.github/agents/*.agent.md` -- parse structured skill and agent tables from `AGENTS.md` and `README.md` -- compare those surfaces deterministically - -## Action 2: add metadata consistency checking - -Deliverables: - -- validate skill and agent count claims in plugin and marketplace metadata -- validate that those claims respect temporary ignore policy where applicable - -## Action 3: validate exact path casing - -Deliverables: - -- build canonical tracked path index from git -- validate explicit path references in canonical surfaces -- report exact mismatches with file and line detail - -## Action 4: validate skill runtime-facing references - -Deliverables: - -- verify `Load References On Demand` paths exist -- verify explicit script/doc/reference paths in skills exist where they are presented as canonical usage guidance - -## Action 5: improve ub-workflow scaffold completeness visibility - -Deliverables: - -- scan generated initiative output for unresolved placeholders -- classify placeholders by severity -- support optional strict failure mode - -## Action 6: align local workflow and CI - -Deliverables: - -- Taskfile tasks covering new integrity scripts -- CI tasks matching the same integrity coverage -- no separate hidden CI-only checks for the baseline suite - -## Action 7: add minimal packaging-policy documentation - -Deliverables: - -- define required versus optional skill assets -- define expectations for agents/scripts/tests/docs where relevant -- keep the policy small and actionable - -## Action 8: consider advisory policy layers only after baseline integrity ships - -Deliverables: - -- freshness guidance if still needed -- optional tier signaling if it serves maintainers rather than aesthetics -- clarified distinction between mandatory policy and more opinionated defaults if portability friction persists - ---- - -## 19. Example deliverables - -Expected concrete outputs from this initiative may include: - -- `.agents/skills/ub-governance/scripts/check_repo_catalog.py` -- `.agents/skills/ub-governance/scripts/check_package_metadata.py` -- `.agents/skills/ub-governance/scripts/check_repo_paths.py` -- `.agents/skills/ub-governance/scripts/check_skill_schema.py` -- `.agents/skills/ub-governance/references/skill-frontmatter.schema.json` -- `.agents/skills/ub-workflow/scripts/check_scaffold_placeholders.py` -- `docs/skill-schema.md` or equivalent packaging-policy doc -- Taskfile tasks for all core checks -- CI workflow updates invoking the same checks -- documented temporary-ignore mechanism for transitional entries such as `Explore` - ---- - -## 20. Acceptance criteria - -This initiative is complete when all of the following are true: - -1. The repository has a working catalog integrity checker. -2. The repository has a working metadata consistency checker. -3. The repository has a working exact path/case validator. -4. The repository has a working minimal skill schema/reference validator. -5. Core integrity checks run locally and in CI with the same baseline coverage. -6. `ub-workflow` scaffold placeholder validation exists and reports deterministically. -7. The baseline integrity suite ignores temporary/test surfaces by default. -8. The repository can tolerate explicit temporary exceptions such as `Explore` without hiding real mismatches. -9. Canonical future guidance converges on `AGENTS.md`. -10. Contributors have a documented minimal packaging contract to follow. - ---- - -## 21. Open questions - -1. Should the temporary ignore list live in code, config, or repository metadata? -2. Should marketplace metadata validate only counts, or also constrained descriptive phrases? -3. Should path/case validation be strict for all canonical surfaces immediately, or staged? -4. When the repository fully converges on `AGENTS.md`, should any residual legacy-cased file be automatically treated as a violation? -5. Is freshness metadata worth introducing before the baseline integrity suite has proven stable? -6. Would a generated catalog become worthwhile later, or is disk truth sufficient long-term? -7. How much of the repository’s stylistic rigidity should be treated as invariant policy versus reusable default? -8. Should packaging expectations stay purely documentary, or should they become partially enforceable by tooling? - ---- - -## 22. Recommended execution order - -1. Build the repository catalog checker. -2. Build the package/marketplace metadata checker. -3. Build the exact path/case validator. -4. Add Taskfile and CI parity for those checks. -5. Add minimal skill schema and runtime-reference validation. -6. Add `ub-workflow` placeholder completeness validation. -7. Document minimal packaging policy. -8. Consider advisory freshness policy. -9. Consider optional tier signaling last. - ---- - -## 23. Final recommendation - -Do not overengineer this. - -The repository does not need a grand content-management system. It needs a reliable self-checking baseline grounded in tracked files and canonical repository surfaces. - -The best next move is to ship the smallest integrity system that catches real drift: - -- inventory mismatches -- stale renamed references -- path/case mistakes -- metadata count drift -- broken skill reference paths -- low-noise workflow scaffold validation - -Then, and only then, add the lighter policy layers around packaging clarity, freshness, and portability guardrails. - -That solves the real problem without turning governance into ceremony. - ---- - -## 24. Durable note for future revisit - -This PRD intentionally assumes no memory of previous discussion. - -The key durable truths it captures are: - -- `ub-workflow` is the canonical successor to `ub-initiative-flow` -- the README and Taskfile have already been updated for that rename -- `AGENTS.md` is the intended canonical root registry standard -- `Explore` is a temporary documented artifact intended for removal -- the repository’s highest-value missing capability is a low-noise, repository-wide integrity layer -- stronger repository-wide validation should absorb the best lessons from the older analysis notes without requiring those notes to remain as separate source documents - ---- - -## 25. Verification addendum (2026-04-16) - -This addendum records the post-PRD verification work that was completed before -roadmap generation so the initiative can proceed without relying on chat -history. - -### Verified external contract notes - -1. Official VS Code and GitHub Copilot documentation now confirm that - `AGENTS.md` is the supported agent-instructions filename for the relevant - environments that this repository targets. -2. Official VS Code custom-agent documentation distinguishes built-in agents - from workspace-defined custom agents discovered from `.github/agents/`. -3. That distinction means `Explore` should be removed from repository inventory - and metadata counts, while remaining valid as a built-in subagent reference - inside local `.agent.md` files when the platform supports it. -4. For filename, instructions, and custom-agent behavior, official GitHub and - VS Code documentation are the primary sources of truth for this initiative. - Research papers may still inform later quality or portability work, but they - are secondary for product-contract questions. - -### Verified repository truth notes - -1. `ub-workflow` has fully replaced `ub-initiative-flow` on disk; the old name - no longer appears in canonical repository surfaces outside planning notes. -2. `Taskfile.yml` already includes `test-workflow`, but `.github/workflows/quality.yml` - does not yet run the workflow regression suite in CI. -3. `pyproject.toml` version metadata currently diverges from `plugin.json` and - `.github/plugin/marketplace.json`. -4. The repository currently uses `AGENTS.MD` on disk, so the roadmap treats the - `AGENTS.MD` to `AGENTS.md` change as an explicit migration step rather than - as an already-completed fact. - -### Derived planning decisions - -1. Sprint 01 should align public inventory, remove `Explore` from published - repository agent counts, and complete the root-registry rename to - `AGENTS.md`. -2. The repository-wide integrity baseline should validate only authoritative - surfaces by default and exclude `tmp/` plus fixture-like content unless - explicitly asked to scan broader scope. -3. The initiative should use a Level 1 governance bridge with the `lean` - profile so validation, final audit language, and follow-up decisions are - explicit without forcing ADR or evidence-heavy workflows in every sprint. diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/research/.gitkeep b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/research/.gitkeep deleted file mode 100644 index 2fa992c..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/research/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -keep diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/research/2026-04-15-uncle-bob-repository-self-governance-hardening-prd.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/research/2026-04-15-uncle-bob-repository-self-governance-hardening-prd.md deleted file mode 100644 index 1d6d7d9..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/research/2026-04-15-uncle-bob-repository-self-governance-hardening-prd.md +++ /dev/null @@ -1,993 +0,0 @@ -# Repository Self-Governance Hardening PRD - -> This document is the complete standalone product and execution specification for hardening the Uncle Bob / itech-agents repository so that its inventories, documentation, metadata, packaging conventions, workflow assets, and maintenance expectations stay aligned over time. - -Date: 2026-04-15 -Project name in repository metadata: `uncle-bob` -Local repository inspected for this revision: `/Users/itechnology/Dev/itech-agents` -Primary repository URL: `https://github.com/robert-hoffmann/uncle-bob` -Status: revised after repository truth check and consolidation of prior analysis notes - ---- - -## 1. Executive summary - -This repository is already much stronger than a typical skill collection. It has real architecture, layered responsibilities, executable support in key areas, and a meaningful distinction between core policy and specialized skills. - -Its strongest traits are: - -- a layered instruction model centered on `AGENTS.md`, `ub-quality`, and sibling specialization -- strong separation of concerns across skills -- progressive disclosure through references instead of one giant instruction blob -- real operational tooling in `ub-governance` and `ub-workflow` -- actual tests for some critical paths rather than purely aspirational quality claims - -The repository’s main weakness is not conceptual quality. The main weakness is that the maintenance automation has not caught up with the architecture. - -The repository still depends on manual consistency across several public surfaces: - -- on-disk skills -- on-disk agent definitions -- root registry guidance -- README tables and install instructions -- plugin metadata -- marketplace metadata -- skill-local references and support assets -- workflow scaffolding assets and tests - -Since the earlier analysis, the repository has already moved forward in meaningful ways: - -- `ub-initiative-flow` has been renamed to `ub-workflow` -- the README has already been updated to refer to `ub-workflow` -- the Taskfile has already been updated to point workflow tests at `ub-workflow` - -That means this initiative should not be framed as migration cleanup anymore. The migration is largely done. The actual need now is a durable repository-wide self-governance layer that prevents the next round of drift. - -This PRD therefore focuses on four practical outcomes: - -1. derive repository truth from canonical tracked files and on-disk assets -2. validate public descriptive surfaces against that truth -3. keep checks precise and low-noise by validating only authoritative surfaces by default -4. define enough schema and packaging policy to reduce accidental drift without turning governance into ceremony - -The recommended first implementation slice is intentionally narrow: - -- repository catalog integrity checking -- exact path and case validation -- metadata consistency checking across README and plugin surfaces -- validation of skill reference paths and basic structural contracts -- local and CI parity for those checks - -Broader ideas such as freshness and maturity remain useful, but they are secondary to getting a reliable integrity baseline in place. - ---- - -## 2. Problem statement - -The repository’s core problem is not weak content. It is weak enforcement of repository truth. - -The repository is now large and structured enough that manual synchronization is an operational liability. The likely future failure mode is not one dramatic breakage. It is gradual trust erosion caused by silent drift. - -Observed categories of risk include: - -1. Inventory drift risk - - skills and agents are described in multiple places - - there is no repository-wide validator keeping those surfaces aligned - -2. Documentation and metadata drift - - README, root registry guidance, plugin metadata, and marketplace metadata can silently diverge from actual repository contents - -3. Rename and deprecation drift - - `ub-initiative-flow` has already been migrated to `ub-workflow` - - future renames can leave stale references behind if not validated automatically - -4. Path and case drift - - `AGENTS.md` is the intended canonical root registry standard - - exact path and case validation is required because legacy casing and copied references create avoidable portability bugs - -5. Validation scope ambiguity: the repository contains temporary or - test-oriented content under `tmp/`, and integrity tooling that scans too - broadly will generate noise and become untrusted. - -6. Duplication-driven drift: consistency across many skills appears to be - maintained partly by copied boilerplate rather than strongly enforced shared - contracts, so repeated mistakes can propagate widely when copied. - -7. Uneven hardening: `ub-governance` already includes focused integrity and - regression checks, `ub-workflow` already includes scripts, assets, and - tests, but many language/framework skills still rely mostly on prose quality - and manual upkeep. - -8. Under-specified metadata and packaging conventions: not all packaging - expectations are explicit, maintainers and contributors cannot always tell - what “complete” packaging means for a skill, and tooling cannot safely - depend on loosely implied metadata conventions. - -9. Volatile guidance risk: framework and tooling guidance for Nuxt, Vue, - Tailwind, Python, TypeScript, and Copilot customization can age quickly, - and the repository does not yet have an explicit freshness discipline for - that volatility. - -10. Portability and rigidity risk: some guidance, especially in core-quality - surfaces, may be too rigid for broad reuse across diverse downstream repos, - and without clearer contracts, “quality baseline” can slide into “one - preferred style for everything”. - -In short: the repository has outgrown informal maintenance. - ---- - -## 3. Why this matters - -If this is left alone, the likely outcomes are: - -- a skill gets added on disk but not listed in the registry or README -- a removed or renamed skill remains referenced in canonical docs -- plugin or marketplace metadata continues to sound authoritative while no longer matching reality -- install instructions point to paths or filenames that are wrong -- a skill’s `Load References On Demand` paths drift and no one notices until runtime use -- duplicated boilerplate slowly diverges in meaning across skills -- a checker is eventually added but scans too broadly, flags temporary content, and becomes noisy enough to ignore - -This matters because the repository is not just documentation. It is operational instruction infrastructure for downstream agent behavior. If it cannot describe itself accurately, people will stop trusting it — gradually, quietly, and correctly. - -Self-governance hardening turns silent drift into early visible failure. - ---- - -## 4. Product vision - -Create a repository that is: - -1. Authoritative - - repository truth is derived from canonical tracked files and on-disk assets - -2. Self-validating - - local checks and CI catch inventory drift, stale references, path/case mistakes, metadata mismatches, reference-path breakage, and scaffold issues before they spread - -3. Explicitly scoped - - integrity tooling validates only authoritative repository surfaces by default and ignores temporary or fixture content unless explicitly asked to scan them - -4. Contributor-friendly - - maintainers can add, rename, package, or remove skills and agents without guessing which public surfaces also need updating - -5. Evolution-safe - - fast-moving framework guidance can be reviewed and updated without destabilizing the rest of the repository - -6. Portable enough to travel - - the repository can maintain strong defaults without pretending every downstream repo must share identical stylistic or tooling preferences - ---- - -## 5. Goals - -### Primary goals - -1. Eliminate drift between on-disk repository inventory and published metadata/documentation surfaces. -2. Add precise repository-wide integrity checks that run both locally and in CI. -3. Define explicit authoritative surfaces and explicit non-authoritative surfaces. -4. Reduce path, case, and reference drift. -5. Validate skill reference paths and basic structural contracts. -6. Improve scaffold completeness visibility for `ub-workflow`. -7. Clarify packaging expectations for skills and agents. - -### Secondary goals - -1. Introduce advisory freshness discipline for volatile guidance. -2. Add maturity or packaging-tier signaling only if it improves real maintenance and review decisions. -3. Reduce duplication-driven drift where practical. -4. Make the repository safer to reuse across projects with different local conventions. - ---- - -## 6. Non-goals - -This initiative is not intended to: - -- rewrite the philosophy of the repository -- rewrite every skill for stylistic consistency -- generate all documentation from a master manifest in phase 1 -- semantically parse arbitrary markdown prose beyond defined structured sections -- validate temporary, fixture, or generated content as authoritative metadata by default -- preserve transitional documented artifacts forever -- force a maturity-label system in phase 1 if it does not yet drive decisions -- remove strong quality opinions entirely just to appear more generic - ---- - -## 7. Users and stakeholders - -### Primary stakeholders - -1. Repository maintainer - - needs dependable low-noise checks and clear failure messages - -2. Future contributors - - need to know what files are authoritative, what references must resolve, and what “complete packaging” means - -3. Downstream users of the repo - - need to trust that README, root registry guidance, metadata, and workflow assets match reality - -### Secondary stakeholders - -1. Users consuming workflow scaffolds from `ub-workflow` -2. Anyone relying on plugin/marketplace metadata to understand what the repository contains -3. Teams adopting only parts of the repo and needing clarity about what is essential versus optional - ---- - -## 8. Current-state diagnosis - -### 8.1 The repository is materially stronger than before - -As of this revision: - -- `ub-initiative-flow` has been replaced by `ub-workflow` -- `ub-workflow` exists on disk as a real skill -- `ub-workflow` has a corresponding on-disk agent definition -- the README already reflects `ub-workflow` -- the Taskfile already points workflow tests at `ub-workflow` - -This means the repository has already corrected one major class of earlier drift. - -### 8.2 The repository still lacks a unified integrity layer - -The repository still depends on manual maintenance across: - -- `.agents/skills/*/SKILL.md` -- `.github/agents/*.agent.md` -- `AGENTS.md` as the intended root registry standard -- `README.md` -- `plugin.json` -- `.github/plugin/marketplace.json` -- skill-local references and support assets - -Those surfaces are not yet governed by one repository-level integrity system. - -### 8.3 Strong engineering exists, but only in parts of the repo - -The earlier analysis was right to highlight that the repository is strongest where it treats skills like products rather than prose. - -That is still true now, just with updated naming: - -- `ub-governance` is an engineered subsystem with checks, schemas, and regression tests -- `ub-workflow` is an engineered workflow product with templates, scripts, and tests - -This is good news, not bad news. It means the repo already contains working patterns for how hardening should look. The gap is that those patterns are not yet elevated to a repository-wide maintenance model. - -### 8.4 Transitional artifacts must be handled explicitly - -At the time of this revision, `Explore` is still documented as an agent concept, but it is intended to be removed. The repository hardening design must support temporary explicit ignores for this kind of transitional item instead of treating it as either permanent truth or accidental mismatch. - -### 8.5 Low-noise validation is a requirement, not a nicety - -The repository contains temporary/test-oriented paths such as `tmp/`. Any integrity system that treats every markdown-like surface as authoritative will quickly become noisy and stop being trusted. - -### 8.6 Duplication is a structural risk multiplier - -The deeper notes were correct that consistency here is partly achieved by duplication rather than reuse. - -That does not make the repository weak, but it does create a specific maintenance hazard: - -- repeated wording changes can drift in meaning -- repeated path references can drift in casing -- repeated packaging conventions can diverge silently -- the same bug can spread across multiple skills through copy/paste - -This initiative should therefore reduce duplication-driven risk through validation and clearer contracts, not just more prose. - ---- - -## 9. Core principles for this initiative - -1. Disk truth first - - use tracked on-disk assets and canonical tracked files as the baseline truth - -2. Validate descriptive surfaces against that truth - - do not rely on descriptive docs as the only inventory source - -3. Keep phase 1 practical - - catch high-value drift first before adding broad policy layers - -4. Precision over breadth: false positives are a governance failure. - -5. Explicit exceptions over silent ambiguity: if something is temporarily - ignored, that should be declared intentionally. - -6. Exact path and case correctness matter: canonical names should be enforced - deliberately, not implied loosely. - -7. Validate actual runtime-facing references: if a skill tells the agent to - load a reference file, that path should resolve. - -8. Build on existing hardening: reuse and extend the governance and workflow - foundations already present in the repository. - -9. Prefer contracts over duplicated folklore: when many skills repeat the same - expectations, validate the contract instead of trusting repetition. - -10. Preserve portability where possible: the repository can stay opinionated - without assuming all downstream repos share one exact style stack or - enforcement posture. - ---- - -## 10. Proposed solution overview - -This initiative should be delivered in two layers. - -### Layer 1: Core repository integrity - -A. Repository catalog integrity checker -B. Agent and metadata consistency checker -C. Exact path and case validator -D. Skill reference-path and minimal schema validator -E. Local and CI parity for all core checks - -### Layer 2: Hardening extensions - -F. `ub-workflow` scaffold completeness validator -G. Packaging policy and optional tier signaling -H. Advisory freshness policy for volatile references -I. Selective refactoring of high-duplication shared conventions where validation alone is insufficient - -The recommendation is to ship Layer 1 first. - ---- - -## 11. Detailed product requirements - -## 11.1 Repository catalog integrity checker - -### Requirement - -The repository must have a canonical integrity checker that derives baseline inventory from tracked on-disk skills and validates structured public surfaces against that baseline. - -### Proposed file - -- `.agents/skills/ub-governance/scripts/check_repo_catalog.py` - -### Canonical inputs - -- `.agents/skills/*/SKILL.md` -- `.github/agents/*.agent.md` -- root `AGENTS.md` -- `README.md` -- `plugin.json` -- `.github/plugin/marketplace.json` - -### Default ignore scope - -The checker must ignore the following by default unless explicitly configured otherwise: - -- `tmp/` -- fixtures -- generated outputs -- examples not declared as canonical surfaces - -### Functional behavior - -The checker must: - -1. discover all skills from `.agents/skills/*/SKILL.md` -2. discover all agent definitions from `.github/agents/*.agent.md` -3. parse the canonical skills and agents listed in the root `AGENTS.md` registry tables -4. parse the structured skill and agent tables in `README.md` -5. validate relevant inventory and count claims in `plugin.json` and `.github/plugin/marketplace.json` -6. report mismatches with file and line detail when possible -7. exit non-zero on real violations -8. support an explicit temporary ignore list for transitional entries such as `Explore` - -### Example failures it should catch - -- a skill exists on disk but is missing from `AGENTS.md` -- a skill is listed in `README.md` but does not exist on disk -- a renamed skill such as `ub-initiative-flow` is still referenced in a canonical surface -- marketplace metadata claims a count that does not match tracked assets -- an agent is documented but not present on disk and not listed in the explicit transitional ignore set - -### Example output - -```text -ERROR: Skill present on disk but missing from AGENTS.md: ub-workflow -ERROR: README.md references removed skill name: ub-initiative-flow -ERROR: Marketplace metadata claims 5 agents, but 4 tracked .agent.md files exist -WARNING: Transitional agent entry ignored by policy: Explore -``` - ---- - -## 11.2 Minimal skill schema and reference validator - -### Requirement - -Every skill must comply with a practical structural contract, and every canonical runtime-facing reference path in a skill must resolve. - -### Proposed files - -- `.agents/skills/ub-governance/references/skill-frontmatter.schema.json` -- `.agents/skills/ub-governance/scripts/check_skill_schema.py` - -### Phase-1 contract - -Each `SKILL.md` must contain: - -- YAML frontmatter -- `name` -- `description` -- frontmatter `name` matching the parent directory name -- readable UTF-8 content - -The validator should also confirm that canonical referenced relative paths in the skill actually exist, especially in patterns such as: - -- `Read \`references/...\`` -- `Read \`docs/...\`` -- `Use \`scripts/...\`` -- other explicit path-style guidance that the agent is expected to follow at runtime - -### Why this matters - -The deeper notes correctly identified that repository integrity is not just about top-level inventory. It is also about whether the repository’s own usage instructions resolve to real assets. - -### Deferred contract ideas - -The following may be added later if they prove useful and low-noise: - -- stricter required section taxonomy -- support asset conventions by skill type -- volatility metadata -- maturity metadata - -### Rationale - -Start with structural correctness and reference validity, not ceremonial prose policing. - ---- - -## 11.3 Agent and package metadata validator - -### Requirement - -The repository must validate that package and marketplace metadata still describe the real repository contents accurately. - -### Proposed file - -- `.agents/skills/ub-governance/scripts/check_package_metadata.py` - -### Functional behavior - -The validator must: - -1. compare declared counts and inventory-like claims against tracked skill and agent files -2. validate that referenced repository paths exist and use canonical casing -3. report stale references to removed or renamed skills/agents -4. respect the explicit transitional ignore list for items intentionally pending removal - -### Example failures it should catch - -- `.github/plugin/marketplace.json` claims five agents when only four tracked agent files exist and the fifth is merely a temporary documented artifact -- package metadata describes workflow assets using a stale renamed skill path - ---- - -## 11.4 Path and case validator - -### Requirement - -The repository must validate exact path and case correctness for canonical repository surfaces. - -### Proposed file - -- `.agents/skills/ub-governance/scripts/check_repo_paths.py` - -### Canonical rule - -The intended root registry standard is `AGENTS.md`, and repository guidance should converge on that exact path and casing. - -### Functional behavior - -The validator must: - -1. build a canonical tracked path index from git -2. extract path-like references from canonical surfaces only -3. validate exact path existence and exact casing against tracked paths -4. report line-level mismatches when possible -5. ignore non-authoritative surfaces by default - -### Example failures it should catch - -- `AGENTS.MD` referenced where `AGENTS.md` is the intended standard -- `skill.md` referenced where `SKILL.md` is the tracked canonical file -- stale path references under renamed workflow surfaces - -### Important constraint - -Do not attempt speculative path extraction from arbitrary prose. Validate explicit path-like references and structured sections only. - ---- - -## 11.5 ub-workflow scaffold completeness validation - -### Requirement - -`ub-workflow` scaffold generation must make unresolved placeholders visible and optionally fail in strict mode. - -### Proposed files - -- `.agents/skills/ub-workflow/scripts/check_scaffold_placeholders.py` -- update `.agents/skills/ub-workflow/scripts/scaffold_initiative.py` -- tests under `.agents/skills/ub-workflow/tests/` - -### Functional behavior - -After scaffold generation, the tooling must: - -1. scan generated initiative output for unresolved placeholder tokens -2. classify unresolved placeholders as required or optional -3. print a deterministic unresolved placeholder summary -4. optionally fail in strict mode when required placeholders remain - -### Important scope rule - -Placeholder checks apply to generated initiative artifacts, not to canonical template files by default. - -### Why this matters - -The deeper notes correctly observed that scaffold generation is safe against clobbering but not strict enough about completeness. That is a real quality gap worth closing. - -### Example output - -```text -Scaffold created at ./.ub-workflows/initiatives/2026-04-15-example -Unresolved placeholders: -- REPLACE_OWNER (optional) -- REPLACE_VALIDATION_COMMANDS (optional) -``` - -### Strict-mode failure example - -```text -ERROR: Required placeholder still unresolved after scaffold render: REPLACE_INITIATIVE_NAME -``` - ---- - -## 11.6 Packaging policy and optional tier signaling - -### Requirement - -The repository should define what “complete packaging” means for a skill and whether that packaging level is visible. - -### Problem being solved - -The deeper notes were right that packaging expectations are currently under-specified: - -- some skills have agents -- some have scripts/tests/assets/docs -- some are intentionally prose-first -- but the repository does not make the distinction explicit enough for contributors or tooling - -### Proposed deliverable - -- `docs/skill-schema.md` or equivalent canonical packaging-policy document - -### Minimum policy questions to answer - -1. Which skill assets are always required? -2. Which are optional? -3. When should a skill include `agents/`? -4. When should a skill include `scripts/` and `tests/`? -5. Which metadata fields are safe for tools to depend on? - -### Optional tier model - -If useful, the repo may use lightweight packaging tiers such as: - -- Base: `SKILL.md` plus required references -- Operational: Base plus scripts/tests/assets/docs as needed - -### Constraint - -Do not make this phase-1 mandatory unless it directly improves contributor behavior or automation quality. - ---- - -## 11.7 Freshness discipline for volatile references - -### Requirement - -Fast-moving framework guidance should have an advisory freshness policy. - -### Candidate high-volatility areas - -- Tailwind -- Nuxt -- Vue -- TypeScript -- Python ecosystem tooling recommendations -- Copilot customization behavior and vendor-specific conventions - -### Suggested metadata - -This may live either in frontmatter or adjacent review metadata: - -```yaml -volatility: high -reviewed_at: 2026-04-15 -review_cycle: quarterly -``` - -### Policy - -- freshness should be warning-first, not blocking by default -- stable principles should be distinguishable from volatile setup recipes -- review timestamps should help prioritization, not become performative bureaucracy - -### Additional caution - -The deeper notes correctly pointed out that “latest stable” is philosophically right but operationally underdefined. The freshness layer should therefore guide review rather than pretend to eliminate judgment. - ---- - -## 11.8 Portability guardrails for core quality surfaces - -### Requirement - -Core repository guidance should remain strong, but it should be explicit about what is mandatory repository policy versus what is recommended house style. - -### Problem being solved - -The deeper notes raised a fair concern that `ub-quality` may be too rigid to scale cleanly across diverse downstream repos if every opinion is treated as universally binding. - -### Proposed outcome - -This initiative should not weaken the repository’s standards, but it should clarify: - -- which constraints are fundamental repository policy -- which constraints are style defaults -- which constraints may need explicit downstream opt-out or adaptation - -### Why this matters - -This improves portability without gutting the repository’s identity. - ---- - -## 12. User stories - -### Maintainer stories - -1. As a maintainer, when I add or remove a skill, CI should tell me exactly which canonical surfaces are out of sync. -2. As a maintainer, when I rename a workflow skill or agent, stale references should fail quickly. -3. As a maintainer, when I document a transitional item like `Explore`, I want that exception to be explicit rather than silent. -4. As a maintainer, I want integrity tooling to ignore temporary content by default so I can trust its output. -5. As a maintainer, I want runtime-facing skill references validated so I know instructions are actually usable. -6. As a maintainer, I want clearer packaging expectations so contributors do not have to reverse-engineer the repository’s conventions. - -### Contributor stories - -1. As a contributor, I want a clear definition of authoritative files so I know what must stay aligned. -2. As a contributor, I want local checks and CI to agree. -3. As a contributor using `ub-workflow`, I want unresolved placeholders to be obvious immediately. -4. As a contributor creating a new skill, I want to know what metadata and support assets are expected. - -### Consumer stories - -1. As a downstream user, I want to trust that the repository’s skill and agent descriptions match the actual repository. -2. As a downstream user, I want setup guidance to point at the right canonical filenames and paths. -3. As a downstream user, I want to understand whether a skill is prose-only guidance or a more operationally hardened subsystem. - ---- - -## 13. Scope - -## In scope - -- repository-wide inventory checks across on-disk skills, on-disk agents, `AGENTS.md`, `README.md`, `plugin.json`, and `.github/plugin/marketplace.json` -- exact tracked path and case validation for canonical repository surfaces -- explicit temporary ignore handling for transitional entries such as `Explore` -- low-noise structured parsing of tables and explicit path references -- local Taskfile and CI parity for core integrity checks -- `ub-workflow` scaffold placeholder visibility and strict-mode support -- minimal skill schema and reference-path validation -- packaging-policy clarification -- advisory freshness design -- clearer distinction between mandatory policy and more opinionated defaults where needed for portability - -## Out of scope - -- full generation of docs from a central manifest in phase 1 -- semantic parsing of arbitrary README prose -- immediate deep test retrofits for every skill -- forced maturity labeling across all skills before it is useful -- treating `tmp/` or other temporary content as authoritative repository truth by default -- removing strong repository opinions just to maximize generic reuse - ---- - -## 14. Success metrics - -### Leading indicators - -1. Zero mismatches between on-disk skill inventory and structured registry surfaces. -2. Zero mismatches between on-disk agent inventory and structured metadata surfaces, excluding explicit transitional ignores. -3. Zero canonical path/case mismatches in validated repository surfaces. -4. Zero broken canonical runtime-facing reference paths in validated skills. -5. Zero false positives from temporary or fixture content in default integrity-check mode. -6. Local Taskfile checks and CI run the same integrity suite. -7. `ub-workflow` scaffold checks report unresolved placeholders deterministically. - -### Lagging indicators - -1. future skill/agent renames are caught automatically when docs lag behind -2. repository metadata remains trustworthy after multiple iterative updates -3. contributors do not need informal tribal knowledge to keep repository surfaces aligned -4. consumers can better distinguish between lightly packaged and operationally hardened skills - ---- - -## 15. Risks and mitigations - -### Risk 1: Checker noise kills trust - -Mitigation: - -- validate only canonical surfaces by default -- keep explicit ignore lists small and reviewable -- prefer precise failures over broad heuristics - -### Risk 2: Scope expands too early - -Mitigation: - -- ship core integrity first -- defer broader policy layers until the baseline is solid - -### Risk 3: Freshness metadata becomes theater - -Mitigation: - -- keep freshness advisory initially -- separate stable principles from volatile recipes - -### Risk 4: Transitional exceptions become permanent clutter - -Mitigation: - -- require explicit ignore entries for temporary exceptions -- review and remove them deliberately - -### Risk 5: Canonical filename migration creates temporary inconsistency - -Mitigation: - -- standardize future guidance on `AGENTS.md` -- let path/case validation make any residual legacy casing visible - -### Risk 6: Packaging policy becomes bureaucratic - -Mitigation: - -- keep packaging policy minimal and decision-oriented -- define only what contributors and tooling actually need - -### Risk 7: Portability concerns get ignored because the repo is internally coherent - -Mitigation: - -- explicitly distinguish non-negotiable repository policy from more opinionated defaults -- preserve strong standards without pretending every downstream repo must use the exact same enforcement posture - ---- - -## 16. Dependencies and assumptions - -This PRD assumes: - -- the repository will continue using `.agents/skills/` and `.github/agents/` as canonical asset roots -- the intended root registry filename standard is `AGENTS.md` -- `ub-workflow` is the canonical successor to `ub-initiative-flow` -- existing governance scripts under `ub-governance` are the best place to host repository-wide integrity tooling initially -- `Explore` is temporary and intended for removal, not a permanent on-disk agent requirement -- skill-local path references are part of real repository behavior and should be validated as such - ---- - -## 17. Rollout plan - -## Phase 0: truth alignment and scope definition - -1. declare canonical repository surfaces in writing -2. declare default ignored surfaces in writing -3. declare the temporary ignore treatment for `Explore` -4. converge future documentation and planning on `AGENTS.md` - -## Phase 1: repository integrity baseline - -1. implement repository catalog checker -2. implement package/marketplace metadata checker -3. implement exact path/case validator -4. wire all three into local developer workflow and CI - -## Phase 2: structural hardening - -1. implement minimal skill schema validation -2. validate canonical skill reference paths -3. add targeted test coverage for new checks - -## Phase 3: workflow hardening - -1. add `ub-workflow` generated-output placeholder validator -2. add strict-mode support where useful -3. ensure deterministic test coverage for scaffold validation - -## Phase 4: policy clarification - -1. define minimal packaging policy for skills and agents -2. clarify portability boundaries for core-quality guidance -3. add freshness review metadata only if maintainers still want it -4. add optional tier signaling only if it solves a real problem - ---- - -## 18. Maintainer action list with examples - -## Action 1: create the repository catalog checker - -Deliverables: - -- enumerate skills from `.agents/skills/*/SKILL.md` -- enumerate agents from `.github/agents/*.agent.md` -- parse structured skill and agent tables from `AGENTS.md` and `README.md` -- compare those surfaces deterministically - -## Action 2: add metadata consistency checking - -Deliverables: - -- validate skill and agent count claims in plugin and marketplace metadata -- validate that those claims respect temporary ignore policy where applicable - -## Action 3: validate exact path casing - -Deliverables: - -- build canonical tracked path index from git -- validate explicit path references in canonical surfaces -- report exact mismatches with file and line detail - -## Action 4: validate skill runtime-facing references - -Deliverables: - -- verify `Load References On Demand` paths exist -- verify explicit script/doc/reference paths in skills exist where they are presented as canonical usage guidance - -## Action 5: improve ub-workflow scaffold completeness visibility - -Deliverables: - -- scan generated initiative output for unresolved placeholders -- classify placeholders by severity -- support optional strict failure mode - -## Action 6: align local workflow and CI - -Deliverables: - -- Taskfile tasks covering new integrity scripts -- CI tasks matching the same integrity coverage -- no separate hidden CI-only checks for the baseline suite - -## Action 7: add minimal packaging-policy documentation - -Deliverables: - -- define required versus optional skill assets -- define expectations for agents/scripts/tests/docs where relevant -- keep the policy small and actionable - -## Action 8: consider advisory policy layers only after baseline integrity ships - -Deliverables: - -- freshness guidance if still needed -- optional tier signaling if it serves maintainers rather than aesthetics -- clarified distinction between mandatory policy and more opinionated defaults if portability friction persists - ---- - -## 19. Example deliverables - -Expected concrete outputs from this initiative may include: - -- `.agents/skills/ub-governance/scripts/check_repo_catalog.py` -- `.agents/skills/ub-governance/scripts/check_package_metadata.py` -- `.agents/skills/ub-governance/scripts/check_repo_paths.py` -- `.agents/skills/ub-governance/scripts/check_skill_schema.py` -- `.agents/skills/ub-governance/references/skill-frontmatter.schema.json` -- `.agents/skills/ub-workflow/scripts/check_scaffold_placeholders.py` -- `docs/skill-schema.md` or equivalent packaging-policy doc -- Taskfile tasks for all core checks -- CI workflow updates invoking the same checks -- documented temporary-ignore mechanism for transitional entries such as `Explore` - ---- - -## 20. Acceptance criteria - -This initiative is complete when all of the following are true: - -1. The repository has a working catalog integrity checker. -2. The repository has a working metadata consistency checker. -3. The repository has a working exact path/case validator. -4. The repository has a working minimal skill schema/reference validator. -5. Core integrity checks run locally and in CI with the same baseline coverage. -6. `ub-workflow` scaffold placeholder validation exists and reports deterministically. -7. The baseline integrity suite ignores temporary/test surfaces by default. -8. The repository can tolerate explicit temporary exceptions such as `Explore` without hiding real mismatches. -9. Canonical future guidance converges on `AGENTS.md`. -10. Contributors have a documented minimal packaging contract to follow. - ---- - -## 21. Open questions - -1. Should the temporary ignore list live in code, config, or repository metadata? -2. Should marketplace metadata validate only counts, or also constrained descriptive phrases? -3. Should path/case validation be strict for all canonical surfaces immediately, or staged? -4. When the repository fully converges on `AGENTS.md`, should any residual legacy-cased file be automatically treated as a violation? -5. Is freshness metadata worth introducing before the baseline integrity suite has proven stable? -6. Would a generated catalog become worthwhile later, or is disk truth sufficient long-term? -7. How much of the repository’s stylistic rigidity should be treated as invariant policy versus reusable default? -8. Should packaging expectations stay purely documentary, or should they become partially enforceable by tooling? - ---- - -## 22. Recommended execution order - -1. Build the repository catalog checker. -2. Build the package/marketplace metadata checker. -3. Build the exact path/case validator. -4. Add Taskfile and CI parity for those checks. -5. Add minimal skill schema and runtime-reference validation. -6. Add `ub-workflow` placeholder completeness validation. -7. Document minimal packaging policy. -8. Consider advisory freshness policy. -9. Consider optional tier signaling last. - ---- - -## 23. Final recommendation - -Do not overengineer this. - -The repository does not need a grand content-management system. It needs a reliable self-checking baseline grounded in tracked files and canonical repository surfaces. - -The best next move is to ship the smallest integrity system that catches real drift: - -- inventory mismatches -- stale renamed references -- path/case mistakes -- metadata count drift -- broken skill reference paths -- low-noise workflow scaffold validation - -Then, and only then, add the lighter policy layers around packaging clarity, freshness, and portability guardrails. - -That solves the real problem without turning governance into ceremony. - ---- - -## 24. Durable note for future revisit - -This PRD intentionally assumes no memory of previous discussion. - -The key durable truths it captures are: - -- `ub-workflow` is the canonical successor to `ub-initiative-flow` -- the README and Taskfile have already been updated for that rename -- `AGENTS.md` is the intended canonical root registry standard -- `Explore` is a temporary documented artifact intended for removal -- the repository’s highest-value missing capability is a low-noise, repository-wide integrity layer -- stronger repository-wide validation should absorb the best lessons from the older analysis notes without requiring those notes to remain as separate source documents diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/research/AGENTS.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/research/AGENTS.md deleted file mode 100644 index 21f92cb..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/research/AGENTS.md +++ /dev/null @@ -1,13 +0,0 @@ -# Research — AGENTS.md - -## Scope - -Applies to the `research/` directory inside one initiative root. - -## Local Rules - -- Keep research notes supportive, not authoritative. -- Preserve links back to `./prd.md` and `./roadmap.md` when a research note - materially influenced the approved plan. -- Do not treat research notes as a substitute for making `prd.md` or - `roadmap.md` self-contained. diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/retained-note.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/retained-note.md deleted file mode 100644 index 2def99e..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/retained-note.md +++ /dev/null @@ -1,78 +0,0 @@ -# Retained Note - -Status: complete - -## Outcome - -Repository self-governance hardening completed with a green final validation -baseline and explicit archive-ready status. - -## What Shipped - -Shipped capabilities: - -1. corrected and regression-protected `ub-workflow` lifecycle and scaffold behavior -2. aligned inventory, metadata, and `AGENTS.md` registry truth -3. deterministic repository-integrity validators with local-to-CI parity -4. generated-output placeholder checking and strict-mode readiness support -5. explicit packaging policy with `agents/openai.yaml` marked optional -6. warning-only freshness policy and explicit policy-versus-default boundaries - -## Preserve These Decisions - -Preserve these decisions: - -1. `task check` is the closest local CI mirror and the blocking validation baseline -2. generated-output placeholder enforcement distinguishes required findings - from advisory authoring prompts and handoff markers -3. `agents/openai.yaml` is optional, not a required skill-package surface -4. freshness review for high-volatility skills is advisory-only by default -5. archive remains an explicit human decision after final audit, not an - automatic side effect of green tests - -## Useful Future Notes - -Useful future notes: - -1. packaging, freshness, and placeholder policies now exist as explicit docs, - so future work should update those contracts rather than relying on implied conventions -2. the repository's Python baseline is `uv`, Ruff, direct script execution, - and stdlib `unittest`, not repository-wired mypy or pytest gates -3. built-in `Explore` references may remain inside local agent implementation - details, but the published repository agent inventory is 4 custom agents - -## Deferred Items - -No intentional deferred items were recorded during the final audit. - -## Governance Bridge Summary - -Governance bridge level: `Level 1` - -Profile: `lean` - -No active exceptions or ADR waivers remained open at final audit. - -If governance coordination was active, also record the profile, exception -references, and ADR references that shaped the final decision. - -## Follow-Up Decisions - -No additional follow-up audits or refactors were requested. - -## Validation Baseline - -Final validation commands and outcomes: - -1. `task check` — pass -2. `uv run python .agents/skills/ub-workflow/scripts/check_scaffold_placeholders.py ./.ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening --strict` — pass -3. `uv run python .agents/skills/ub-workflow/scripts/scaffold_initiative.py archive ./.ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening --dry-run` — pass - -Evidence pointer: - -1. `./sprints/11-final-audit/evidence/final-audit-summary.md` - -Documentation synchronization confirmation: - -1. `README.md`, `roadmap.md`, and this retained note were synchronized during - the final audit. diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/roadmap.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/roadmap.md deleted file mode 100644 index 1f1d053..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/roadmap.md +++ /dev/null @@ -1,348 +0,0 @@ -# Sprint Roadmap - -Status: complete - -This is the small live progress document for the initiative. - -This roadmap was generated from `./prd.md` plus the verified planning addendum -recorded on 2026-04-16. After sprint initialization, a workflow gap was -discovered: the sprint pack was scaffolded with placeholder-only sprint PRDs. -The first four sprints below correct `ub-workflow` itself so the original -hardening work can proceed under an execution-ready, resumable sprint model. -Do not start sprint execution until the roadmap is reviewed, explicitly -approved, and the initiative `README.md` records `roadmap_ready: pass`. - -## Overall Checklist - -- [x] Master PRD imported into `./prd.md` -- [x] Master roadmap generated from `./prd.md` -- [x] Roadmap reviewed and approved with `roadmap_ready: pass` -- [x] All sprint folders initialized under `./sprints/` from `./sprint-template/` -- [x] Sprint execution started -- [x] All sprint closeouts completed -- [x] Final audit completed as the last roadmap item -- [x] Follow-up audit or refactor decision recorded -- [x] `./retained-note.md` written - -## Current Position - -- Current sprint: `none` -- Last completed sprint: `Final Audit - Repository Hardening Final Audit` -- Next sprint: `none` -- Resume from: `none` -- Active blockers: `none` - -## Roadmap Objective - -Correct `ub-workflow`'s sprint-preparation and resume model first, then ship a -self-validating repository maintenance baseline that keeps skill inventory, -custom-agent inventory, root instructions, metadata, workflow assets, and -contributor expectations aligned over time while preserving the repository's -existing architecture and low-noise governance posture. - -## PRD Scope Summary - -In scope: - -1. Correct `ub-workflow` so sprint PRDs are prepared as real execution - artifacts before work begins and the workflow remains resumable after - session resets. -2. Align authoritative repository surfaces with verified disk truth, including - removal of `Explore` from published inventory and convergence on - `AGENTS.md`. -3. Add repository-wide integrity automation for catalog, metadata, path or - case, and skill-structure validation with local and CI parity. -4. Harden the workflow scaffold and improve packaging clarity plus targeted - quality uplift for weaker skill surfaces. - -Out of scope: - -1. Full phase-1 generation of all repository docs from a central manifest. -2. Arbitrary semantic validation of prose outside structured or explicit - authoritative surfaces. -3. Deep retrofitting of every skill with scripts or tests before the integrity - baseline proves stable and useful. - -## Sprint Sequence - -Do not run `init-sprints` until this roadmap is complete, reviewed, and the -initiative `README.md` records `roadmap_ready: pass`. - -- [x] Sprint 01 - Lifecycle And Gate Redesign - - Path: `./sprints/01-lifecycle-and-gate-redesign/sprint.md` - - Goal: redesign `ub-workflow`'s lifecycle and gate model so sprint - preparation, review pauses, and archive review are explicit and durable - - Depends on: `none` - - Validation focus: lifecycle consistency across contract, skill, and agent; - explicit gate semantics; and session-reset stop-resume discipline - - Evidence folder: `./sprints/01-lifecycle-and-gate-redesign/evidence/` - - Subtasks: - - [x] Rewrite the workflow contract to include sprint preparation, - optional context refresh, sprint review pauses, and final archive - review. - - [x] Update the skill and companion agent to follow the corrected - lifecycle and gate model. - - [x] Make the session-reset assumption explicit so written artifacts, not - chat history, remain the system of record. - -- [x] Sprint 02 - Skill Agent And Reference Alignment - - Path: `./sprints/02-skill-agent-and-reference-alignment/sprint.md` - - Goal: propagate the corrected workflow lifecycle into every `ub-workflow` - contract, guide, and companion-agent surface - - Depends on: `Sprint 01 - Lifecycle And Gate Redesign` - - Validation focus: contract alignment, user-guide alignment, and removal of - placeholder-shell assumptions from workflow-facing docs - - Evidence folder: `./sprints/02-skill-agent-and-reference-alignment/evidence/` - - Subtasks: - - [x] Update the artifact contract so sprint PRDs are execution-ready - artifacts instead of starter shells. - - [x] Update validation, scaffold-adaptation, and scaffold-helper - references so sprint preparation is a distinct phase before - execution. - - [x] Update the user guide and broader agent wording so the same - lifecycle is taught everywhere. - -- [x] Sprint 03 - Helper And Template Redesign - - Path: `./sprints/03-helper-and-template-redesign/sprint.md` - - Goal: redesign the workflow helper and sprint template so the roadmap can - become real pre-execution sprint PRDs - - Depends on: `Sprint 02 - Skill Agent And Reference Alignment` - - Validation focus: richer roadmap parsing, explicit sprint-preparation - behavior, and clear separation between machine placeholders and human - reasoning fields - - Evidence folder: `./sprints/03-helper-and-template-redesign/evidence/` - - Subtasks: - - [x] Redesign `roadmap_sprint_entries()` so it can consume the richer - sprint metadata already present in the roadmap. - - [x] Add or model an explicit `prepare-sprints` phase before execution. - - [x] Redesign the sprint template so roadmap-derived sections and - human-authored reasoning sections are clearly separated. - -- [x] Sprint 04 - Workflow Regression And Resume Scenarios - - Path: `./sprints/04-workflow-regression-and-resume-scenarios/sprint.md` - - Goal: protect the corrected workflow lifecycle with regression and - session-reset resume coverage - - Depends on: `Sprint 03 - Helper And Template Redesign` - - Validation focus: gating behavior, prepared sprint coverage, - session-reset resume order, and final review pauses before archive - - Evidence folder: `./sprints/04-workflow-regression-and-resume-scenarios/evidence/` - - Subtasks: - - [x] Add regression coverage for the rich-roadmap but empty-sprint failure - mode. - - [x] Add resume scenarios for later sprints after a session reset. - - [x] Add final-audit pause and archive-review coverage. - -- [x] Sprint 05 - Inventory Alignment And AGENTS Rename - - Path: `./sprints/05-inventory-alignment-and-agents-rename/sprint.md` - - Goal: align public inventory surfaces with verified repository truth and - complete the root-registry filename convergence to `AGENTS.md` - - Depends on: `Sprint 04 - Workflow Regression And Resume Scenarios` - - Validation focus: authoritative inventory counts, filename and casing - correctness, README install-path correctness, and version-metadata - reconciliation plan - - Evidence folder: `./sprints/05-inventory-alignment-and-agents-rename/evidence/` - - Subtasks: - - [x] Remove `Explore` from published repository agent inventory and - metadata descriptions while preserving valid built-in subagent - references in local `.agent.md` files. - - [x] Rename `AGENTS.MD` to `AGENTS.md` and update all canonical - references, installation snippets, and validator assumptions. - - [x] Reconcile version drift across `pyproject.toml`, `plugin.json`, and - `.github/plugin/marketplace.json`. - -- [x] Sprint 06 - Repository Integrity Validators - - Path: `./sprints/06-repo-integrity-validators/sprint.md` - - Goal: add the repository-wide integrity baseline under ub-governance using - the existing direct-CLI validation pattern - - Depends on: `Sprint 05 - Inventory Alignment And AGENTS Rename` - - Validation focus: deterministic checker behavior, low-noise authoritative - scope, exact path validation, and runtime-facing skill reference checks - - Evidence folder: `./sprints/06-repo-integrity-validators/evidence/` - - Subtasks: - - [x] Implement `check_repo_catalog.py` for disk-versus-registry - comparison across skills, custom agents, README, and root registry - surfaces. - - [x] Implement `check_package_metadata.py`, `check_repo_paths.py`, and - `check_skill_schema.py` using the smallest shared helper surface that - still keeps CLI execution straightforward. - - [x] Define the ignore-scope behavior so `tmp/` and fixture-like content - are excluded by default. - -- [x] Sprint 07 - CI Parity And Regression Coverage - - Path: `./sprints/07-ci-parity-and-regression-coverage/sprint.md` - - Goal: make local and CI coverage match for the repository-integrity, - governance, and workflow checks - - Depends on: `Sprint 06 - Repository Integrity Validators` - - Validation focus: task-to-CI parity, subprocess regression coverage, - fixture quality, and reproducible failure messages - - Evidence folder: `./sprints/07-ci-parity-and-regression-coverage/evidence/` - - Subtasks: - - [x] Add Taskfile entrypoints for the new integrity checkers and ensure - `check` is the closest local CI mirror. - - [x] Extend `.github/workflows/quality.yml` so workflow regression tests - and the new integrity baseline run in CI. - - [x] Add pass and fail fixtures for inventory drift, version drift, - broken references, path-case mismatches, and ignored `tmp/` scope. - -- [x] Sprint 08 - Workflow Placeholder Hardening - - Path: `./sprints/08-workflow-placeholder-hardening/sprint.md` - - Goal: make unresolved scaffold placeholders visible and optionally blocking - for generated initiative output - - Depends on: `Sprint 07 - CI Parity And Regression Coverage` - - Validation focus: placeholder token contract clarity, deterministic output, - strict-mode behavior, and regression coverage for generated initiative - artifacts - - Evidence folder: `./sprints/08-workflow-placeholder-hardening/evidence/` - - Subtasks: - - [x] Define the placeholder token contract in ub-workflow references or - docs so the checker validates an explicit rule. - - [x] Add `check_scaffold_placeholders.py` and integrate it with - `scaffold_initiative.py` as appropriate. - - [x] Extend workflow tests with required-versus-optional placeholder - cases. - -- [x] Sprint 09 - Packaging Policy And Targeted Skill Uplift - - Path: `./sprints/09-packaging-policy-and-skill-uplift/sprint.md` - - Goal: document the repository packaging contract and improve the weakest or - least consistent skill surfaces without broad churn - - Depends on: `Sprint 08 - Workflow Placeholder Hardening` - - Validation focus: policy clarity, packaging consistency, targeted skill - improvements, and minimal-diff discipline - - Evidence folder: `./sprints/09-packaging-policy-and-skill-uplift/evidence/` - - Subtasks: - - [x] Create the canonical packaging-policy document and define required - versus optional skill assets. - - [x] Decide whether `agents/openai.yaml` is required, optional, or - deprecated and make the policy enforceable or consistently optional. - - [x] Deepen `ub-python` and normalize high-value structural inconsistencies - such as missing output-contract sections where they improve contributor - guidance. - -- [x] Sprint 10 - Freshness And Portability Review - - Path: `./sprints/10-freshness-and-portability-review/sprint.md` - - Goal: add warning-only freshness discipline for volatile skills and clarify - which quality rules are repository policy versus strong defaults - - Depends on: `Sprint 09 - Packaging Policy And Targeted Skill Uplift` - - Validation focus: advisory-only behavior, portability clarity, and absence - of bureaucratic or blocking side effects - - Evidence folder: `./sprints/10-freshness-and-portability-review/evidence/` - - Subtasks: - - [x] Propose freshness metadata or review-cycle markers for high-volatility - skill surfaces. - - [x] Clarify policy-versus-default language in the core quality surfaces - where portability friction is most likely. - - [x] Confirm that the advisory layer does not weaken the integrity - baseline or create noisy blocking checks. - -- [x] Final Audit - Repository Hardening Final Audit - - Path: `./sprints/11-final-audit/sprint.md` - - Goal: verify full implementation completeness, synchronization, and - follow-up needs - - Depends on: `Sprint 10 - Freshness And Portability Review` - - Validation focus: completeness review, documentation synchronization, - final quality gates, and follow-up audit or refactor review - - Evidence folder: `./sprints/11-final-audit/evidence/` - - Subtasks: - - [x] Confirm no material roadmap scope was missed - - [x] Confirm documentation and synchronized artifacts are current where - applicable - - [x] Ask whether follow-up audits or refactors are wanted and record the - answer - -## Dependency Chain - -1. Sprint 01 corrects the `ub-workflow` lifecycle and gate model so later work - can depend on a real sprint-preparation phase. -2. Sprint 02 propagates that lifecycle across the workflow contracts, guides, - and companion-agent surfaces. -3. Sprint 03 turns the corrected lifecycle into helper and template behavior - that can produce real sprint PRDs. -4. Sprint 04 protects those workflow behaviors with regression and resume - scenarios. -5. Sprint 05 establishes the authoritative public inventory, metadata baseline, - and `AGENTS.md` path contract that later validators must enforce. -6. Sprint 06 codifies that truth into deterministic repository-wide checkers. -7. Sprint 07 makes those checkers reproducible across local and CI execution. -8. Sprint 08 extends the same integrity posture into `ub-workflow`'s generated - output surface. -9. Sprint 09 documents packaging policy and applies targeted quality upgrades - after the structural baseline is in place. -10. Sprint 10 adds advisory freshness and portability follow-through without - destabilizing the blocking baseline. -11. Final Audit verifies that every prior sprint actually landed and that no - required synchronized artifact was skipped. - -## Validation Focus Per Sprint - -1. Sprint 01: lifecycle consistency, gate clarity, session-reset discipline, - and explicit human review checkpoints. -2. Sprint 02: contract alignment, guide alignment, and elimination of - placeholder-shell assumptions from workflow-facing docs. -3. Sprint 03: richer roadmap parsing, sprint-preparation behavior, and template - semantics for execution-ready sprint PRDs. -4. Sprint 04: regression protection for the discovered failure mode, - session-reset resume order, and final review pauses. -5. Sprint 05: inventory correctness, file-path correctness, public metadata - consistency, and install-instruction accuracy. -6. Sprint 06: deterministic checker behavior, UTF-8 handling, exact path or - case validation, and low-noise authoritative-scope enforcement. -7. Sprint 07: local versus CI parity, regression fixture breadth, and clear - failure reporting. -8. Sprint 08: placeholder token detection accuracy, strict-mode behavior, and - generated-output scope discipline. -9. Sprint 09: policy clarity, packaging consistency, and focused skill-surface - improvements with minimal unrelated churn. -10. Sprint 10: advisory freshness usefulness, portability clarity, and absence - of new blocking noise. -11. Final Audit: completeness review, synchronized artifacts, final validation - gates, and follow-up review. - -## Roadmap Review Checklist - -Review this roadmap against the workflow approval gate before setting -`roadmap_ready: pass`. - -1. Sprint breakdown completeness: does the roadmap cover the workflow-correction - prerequisite plus the original hardening work without silently dropping any - approved scope? -2. Ordering and dependencies: does each sprint depend on the smallest sensible - predecessor, and does the sequence preserve a stable workflow and integrity - baseline before broader quality uplift? -3. Scope boundaries and non-goals: does the roadmap keep phase-1 work focused - on authoritative surfaces and avoid sliding into arbitrary prose policing or - manifest generation? -4. Validation and documentation expectations: are the validation focus, - evidence locations, README or roadmap updates, and final-audit obligations - explicit enough for another operator to resume without chat history? - -## Final Audit Step - -The final audit must confirm at minimum: - -1. roadmap scope was actually executed -2. no material work was silently skipped -3. synchronized docs, tests, and related artifacts are current where applicable -4. required validation has been run or explicitly deferred -5. the user was asked about follow-up audits or refactors -6. the retained note reflects the final state - -## Handoff Expectations - -1. Resume from `./roadmap.md` first, then open the active or next sprint's - `sprint.md`, then the latest `closeout.md` once execution has begun. -2. Keep each sprint `sprint.md` standalone so execution does not depend on chat - history or reopening the master `prd.md`. -3. Save deterministic evidence under the active sprint's `./evidence/` folder - before changing sprint state. -4. Update this roadmap and `./README.md` after every meaningful sprint status - change. - -## Initiative Completion Condition - -The initiative is complete only when: - -1. all roadmap items have closeout records -2. the final audit sprint ends with a passing completion decision -3. required validation scenarios are covered and traceable -4. the canonical docs and synchronized artifacts are current -5. `./retained-note.md` has been written with the final follow-up decision diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/.gitkeep b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/.gitkeep deleted file mode 100644 index 2fa992c..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -keep diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/01-lifecycle-and-gate-redesign/closeout.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/01-lifecycle-and-gate-redesign/closeout.md deleted file mode 100644 index 26c7664..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/01-lifecycle-and-gate-redesign/closeout.md +++ /dev/null @@ -1,141 +0,0 @@ -# Sprint Closeout - -## environment_note - -Executed in the local macOS workspace at -`/Users/itechnology/Dev/itech-agents`. Sprint 01 changed only the three -workflow-authority surfaces plus this sprint's evidence and closeout records: -`./.agents/skills/ub-workflow/references/workflow-contract.md`, -`./.agents/skills/ub-workflow/SKILL.md`, and -`./.github/agents/ub-workflow.agent.md`. - -## scope_note - -This sprint redesigned the `ub-workflow` lifecycle and gate model, made the -session-reset assumption explicit, and aligned the companion skill and agent to -that revised contract. It did not redesign helper behavior, sprint templates, -tests, or user-guide/reference surfaces beyond the minimum agent changes needed -to stop contradicting the new lifecycle. Governance bridge: `Level 1`, profile -`lean`. - -## decision_note - -Chosen path: rewrite the workflow contract first, then make the skill and -companion agent follow it. - -Rejected alternative: jump directly to helper and template changes before -redefining the lifecycle contract. - -Pros of the rejected alternative: - -1. It could make the current sprint-generation failure disappear quickly. -2. It would produce visible artifact changes early. - -Cons of the rejected alternative: - -1. It would leave the phase and gate semantics ambiguous. -2. It would risk the helper, skill, and agent drifting in different - directions. -3. It would make later test and documentation work unstable because the - contract would still be moving. - -## gate_note - -sprint_closeout: pass - -Sprint 01 completed its planned contract work. The workflow contract, skill, -and companion agent now share an explicit lifecycle that includes -sprint-content preparation, optional sprint-start readiness, review pauses -after sprint closeout and final audit, and explicit archive review. - -confidence: pass - -When governance is active, also record the governance gate type and result as -`merge|confidence|release: pass|fail|blocked`. - -## exception_note - -none - -When governance is active, reference exception records that use the canonical -governance exception metadata. - -## validation_note - -Validation commands and outcomes: - -1. `npx --yes markdownlint-cli2 .agents/skills/ub-workflow/references/workflow-contract.md .agents/skills/ub-workflow/SKILL.md .github/agents/ub-workflow.agent.md .ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening/sprints/01-lifecycle-and-gate-redesign/closeout.md .ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening/sprints/01-lifecycle-and-gate-redesign/evidence/lifecycle-summary-and-gates.md` - - Expected final result for this sprint: pass. - -1. Manual cross-read of the three workflow authority surfaces - - Result: pass; the lifecycle, gate vocabulary, and review checkpoints now - describe the same sequence across contract, skill, and agent. - -Documentation and synchronized-artifact validation: - -1. The contract is now the source of truth for sprint preparation and archive - review semantics. -2. The skill now follows that contract instead of implying that sprint - initialization alone is enough before execution. -3. The agent now exposes sprint-pack preparation as an explicit lifecycle step. - -Also record any documentation or synchronized-artifact validation that was required for this sprint. - -When tests changed, record whether TG001-TG005 checks were run and what they -reported. - -When governance is active, record governance-level validation commands, profile, -ADR references, and evidence paths that informed the gate decision. - -## done_verification_note - -Sprint 01 definition of done is satisfied. - -1. Planned functionality implemented: yes -2. Known in-scope errors still open: none within Sprint 01 scope -3. Required quality gates green: markdown validation expected green after the - final Sprint 01 closeout and evidence write; no test-signal changes were in - scope for this sprint -4. Relevant docs and synchronized artifacts updated or explicitly unchanged: - updated -5. Validation evidence recorded: yes - -Minimum questions to answer: - -1. Is the planned functionality implemented? -2. Are there any known in-scope errors still open? -3. Are the required project quality gates green, including TG001-TG005 checks - when tests changed? -4. Are the relevant docs and synchronized artifacts updated or explicitly unchanged? -5. Is the validation evidence recorded? - -## handoff_note - -1. Finished: the `ub-workflow` lifecycle and gate model were redesigned across - the workflow contract, skill, and companion agent. -2. Open: the rest of the `ub-workflow` reference set, helper behavior, - template behavior, and regression suite still need to be aligned in Sprints - 02 through 04. -3. Next recommended action: start Sprint 02 - Skill Agent And Reference - Alignment. -4. The next sprint should read this closeout first, then re-open - `./.agents/skills/ub-workflow/references/workflow-contract.md`, - `./.agents/skills/ub-workflow/SKILL.md`, and - `./.github/agents/ub-workflow.agent.md`. - -## follow_up_note - -No extra follow-up work was requested during Sprint 01 beyond the planned -Sprint 02 through Sprint 04 workflow-correction sequence. Proceed to Sprint 02 -next. - -For the final audit sprint, answer at minimum: - -1. Was the user asked whether they want follow-up audits or refactors? -2. Which follow-up items were requested, if any? -3. Which follow-up items were explicitly declined, if any? -4. Did the final validation and documentation synchronization checks pass? -5. Are any governance exceptions, ADR waivers, or follow-up validation items - still open? diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/01-lifecycle-and-gate-redesign/evidence/lifecycle-summary-and-gates.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/01-lifecycle-and-gate-redesign/evidence/lifecycle-summary-and-gates.md deleted file mode 100644 index 4d7f36b..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/01-lifecycle-and-gate-redesign/evidence/lifecycle-summary-and-gates.md +++ /dev/null @@ -1,48 +0,0 @@ -# Sprint 01 Evidence - -## Before And After Lifecycle Summary - -Before Sprint 01, `ub-workflow` compressed the lifecycle to discovery, PRD, -roadmap, sprint initialization, sprint execution, final audit, and retained -note. That model left one critical gap: it did not recognize sprint-content -preparation as a first-class phase, so an initiative could have a rich roadmap -but still end up with placeholder-only `sprint.md` files. - -After Sprint 01, the lifecycle is explicitly: - -1. research and discovery -2. PRD authoring and readiness -3. initiative scaffold and baseline setup -4. roadmap generation and approval -5. sprint-content preparation -6. sprint materialization and start readiness -7. ordered sprint execution -8. sprint closeout and review pause -9. final audit and review pause -10. retained note and archive decision - -The practical change is that roadmap approval no longer implies execution -readiness by itself. Sprint content must be prepared, written down, and -reviewable before any sprint begins. - -## Gate Glossary - -- `research_ready`: discovery is grounded enough to support a durable PRD -- `prd_ready`: the PRD is execution-ready and roadmap work can start -- `roadmap_ready`: the roadmap is execution-ready and approved for downstream - work -- `sprint_content_ready`: the sprint pack has execution-ready sprint PRDs -- `sprint_start_ready`: the next sprint can begin after any needed context - refresh -- `sprint_closeout`: the active sprint is safe to pause, hand off, or close -- `archive_ready`: final audit output is ready for explicit archive review -- `initiative_complete`: the initiative has completed final audit and retained - note - -## Ownership Notes - -- `roadmap_ready` remains a human-owned review checkpoint. -- `archive_ready` remains a human-owned review checkpoint. -- The other gates are shared workflow gates that can be evaluated by the - operator or agent, but their rationale must be written into initiative - artifacts. diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/01-lifecycle-and-gate-redesign/sprint.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/01-lifecycle-and-gate-redesign/sprint.md deleted file mode 100644 index b7c6aa5..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/01-lifecycle-and-gate-redesign/sprint.md +++ /dev/null @@ -1,134 +0,0 @@ -# Sprint PRD - -## Summary - -Redesign `ub-workflow`'s lifecycle and gate model so the initiative can be run -under a workflow that preserves resumability after session resets instead of -relying on placeholder sprint shells. This sprint establishes the explicit -phase model, gate vocabulary, stop-resume discipline, and pause-before-next-step -behavior that the later workflow-correction sprints and the original -repository-hardening sprints will depend on. - -## Scope - -1. Redefine the canonical lifecycle for `ub-workflow` so it explicitly covers - research and discovery, PRD readiness, initiative scaffold, roadmap - generation and approval, sprint-content preparation, sprint materialization, - optional context refresh before execution, one-sprint execution, sprint - closeout and review pause, final audit pause, and explicit archive review. -2. Define the gate vocabulary needed to enforce that lifecycle, including - `research_ready`, `prd_ready`, `roadmap_ready`, `sprint_content_ready`, - optional `sprint_start_ready`, `sprint_closeout`, `archive_ready`, and - `initiative_complete`. -3. Decide which checkpoints are human-owned approvals versus machine-enforced - blockers so the workflow remains rigorous without becoming bureaucratic. -4. Make the session-reset assumption explicit: written artifacts are the system - of record, not chat history. - -## Dependencies - -1. This sprint has no prior sprint dependency. -2. Use the current `ub-workflow` contract surfaces in - `./.agents/skills/ub-workflow/` and `./.github/agents/ub-workflow.agent.md` - as the concrete baseline for redesign. -3. Use the discovered workflow gap in the current initiative's placeholder-only - sprint generation as the motivating failure mode this sprint must correct. - -## Repository Truth At Sprint Start - -1. `./.agents/skills/ub-workflow/references/workflow-contract.md` currently - compresses the lifecycle to discovery, PRD, roadmap, sprint initialization, - sprint execution, final audit, and retained note. -2. `./.agents/skills/ub-workflow/SKILL.md` currently treats sprint - initialization as the last planning step before execution, even though the - current initiative proved that initialized sprint folders can still contain - empty placeholder sprint PRDs. -3. `./.github/agents/ub-workflow.agent.md` currently routes users from roadmap - generation to sprint initialization without a distinct sprint-preparation - phase. -4. The current initiative already exposed the operational failure mode: the - roadmap was rich, but the generated sprint PRDs were not execution-ready. - -## Chosen Path - -Rewrite the workflow contract first, then make the skill and companion agent -follow it. That keeps the lifecycle authority in one place and avoids helper, -template, or guide changes being built on top of unclear phase semantics. - -## Rejected Alternative - -Jump directly to helper and template changes before redefining the lifecycle -contract. - -Pros: - -1. Could make the current sprint-generation failure disappear quickly. -2. Produces visible artifact changes early. - -Cons: - -1. Leaves the underlying phase and gate semantics ambiguous. -2. Risks the helper, skill, and agent drifting in different directions. -3. Makes later test and documentation work unstable because the contract would - still be moving. - -## Affected Areas - -1. `./.agents/skills/ub-workflow/references/workflow-contract.md` -2. `./.agents/skills/ub-workflow/SKILL.md` -3. `./.github/agents/ub-workflow.agent.md` -4. The current initiative roadmap and sprint pack only as downstream consumers - of the corrected contract, not as primary implementation surfaces in this - sprint - -## Validation Plan - -1. Re-read the updated workflow contract, skill, and agent together to confirm - they all describe the same lifecycle order and the same gate vocabulary. -2. Run `npx --yes markdownlint-cli2` on the three touched workflow surfaces. -3. Record one before/after lifecycle summary and one gate glossary in - `./evidence/` so Sprint 02 can treat the new contract as authoritative. -4. Record the explicit session-reset rule and the smallest required resume file - set in the sprint closeout. -5. For the Level 1 `lean` governance bridge, note which checkpoints are - deliberately human-owned approvals rather than mechanical blockers. - -## Exit Criteria - -1. The workflow contract, skill, and companion agent share one explicit - lifecycle and gate model. -2. The contract explicitly covers a sprint-preparation phase before execution, - a review pause after every sprint, and a final pause before archive. -3. Sprint closeout gives Sprint 02 a stable lifecycle contract to propagate - across the rest of the `ub-workflow` documentation surface. - -## Final Audit Checklist - -Use this checklist only when this sprint is the final audit sprint. - -- [ ] roadmap scope was actually executed or explicitly deferred -- [ ] no material work was silently skipped -- [ ] initiative-level validation is recorded and traceable -- [ ] relevant documentation and synchronized artifacts reflect the shipped behavior -- [ ] follow-up audit or refactor decisions were captured -- [ ] `retained-note.md` is ready to record the final state - -## Handoff Expectation - -Sprint 02 should read this sprint's `closeout.md` first, then re-open the final -workflow contract, skill, and agent. Its first task is to propagate the new -lifecycle into the artifact contract, validation contract, scaffold guidance, -and user-facing workflow guide without re-opening the Sprint 01 design -decisions. - -## Definition Of Done - -This sprint is done only when all of the following are true: - -1. planned functionality is complete or explicitly blocked -2. known in-scope issues are documented -3. required validation is run or explicitly deferred -4. relevant documentation and synchronized artifacts are updated or explicitly marked unchanged -5. validation evidence is recorded and traceable -6. governance bridge requirements are satisfied or explicitly marked not applicable -7. closeout is current and resumable diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/02-skill-agent-and-reference-alignment/closeout.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/02-skill-agent-and-reference-alignment/closeout.md deleted file mode 100644 index 1f7b294..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/02-skill-agent-and-reference-alignment/closeout.md +++ /dev/null @@ -1,138 +0,0 @@ -# Sprint Closeout - -## environment_note - -Executed in the local macOS workspace at -`/Users/itechnology/Dev/itech-agents`. Sprint 02 changed the `ub-workflow` -reference and guide surfaces targeted by the sprint plus the Sprint 02 evidence -and closeout artifacts. - -## scope_note - -This sprint propagated Sprint 01's lifecycle redesign across the broader -`ub-workflow` contract and guide surfaces: artifact contract, validation and -completion contract, scaffold adaptation guidance, scaffold-helper guidance, -user guide, and remaining companion-agent wording. It did not redesign helper -behavior, roadmap parsing, sprint templates, or regression tests; those remain -Sprint 03 and Sprint 04 work. Governance bridge: `Level 1`, profile `lean`. - -## decision_note - -Chosen path: update the workflow contracts and guides in place so there is one -canonical explanation of the corrected lifecycle. - -Rejected alternative: leave the documentation surfaces mostly unchanged and -rely on helper behavior alone to teach the new workflow. - -Pros of the rejected alternative: - -1. It would reduce immediate documentation churn. -2. It would keep the redesign concentrated in scripts. - -Cons of the rejected alternative: - -1. It would leave contradictory user guidance across the workflow surfaces. -2. It would make the workflow harder to resume correctly after a session reset. -3. It would undermine trust because the docs would still teach the old path. - -## gate_note - -sprint_closeout: pass - -Sprint 02 completed the planned reference-alignment work. The workflow -contracts, scaffold guidance, user guide, and remaining companion-agent wording -now all describe sprint-pack preparation as an explicit phase before sprint -execution. - -confidence: pass - -When governance is active, also record the governance gate type and result as -`merge|confidence|release: pass|fail|blocked`. - -## exception_note - -none - -When governance is active, reference exception records that use the canonical -governance exception metadata. - -## validation_note - -Validation commands and outcomes: - -1. `npx --yes markdownlint-cli2 .agents/skills/ub-workflow/references/artifact-contracts.md .agents/skills/ub-workflow/references/validation-and-completion.md .agents/skills/ub-workflow/references/scaffold-adaptation.md .agents/skills/ub-workflow/references/scaffold-helper.md .agents/skills/ub-workflow/docs/user-guide.md .github/agents/ub-workflow.agent.md .ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening/sprints/02-skill-agent-and-reference-alignment/closeout.md .ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening/sprints/02-skill-agent-and-reference-alignment/evidence/reference-alignment-summary.md .ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening/README.md .ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening/roadmap.md` - - Expected final result for this sprint: pass. - -1. Manual cross-read of the touched workflow references, guide, and companion - agent - - Result: pass; none of the touched files still imply that roadmap approval - plus `init-sprints` alone is sufficient for sprint execution. - -Documentation and synchronized-artifact validation: - -1. The artifact contract now defines `sprint.md` as an execution-ready sprint - PRD rather than a starter shell. -2. The validation contract now names `research_ready`, - `sprint_content_ready`, `sprint_start_ready`, and `archive_ready`. -3. The scaffold guidance now distinguishes helper capabilities from the still - separate sprint-preparation step. -4. The user guide now teaches sprint-pack preparation explicitly in both usage - flow and smoke prompts. - -Also record any documentation or synchronized-artifact validation that was required for this sprint. - -When tests changed, record whether TG001-TG005 checks were run and what they -reported. - -When governance is active, record governance-level validation commands, profile, -ADR references, and evidence paths that informed the gate decision. - -## done_verification_note - -Sprint 02 definition of done is satisfied. - -1. Planned functionality implemented: yes -2. Known in-scope errors still open: none within Sprint 02 scope -3. Required quality gates green: markdown validation expected green after the - final Sprint 02 closeout and evidence write; no test-signal changes were in - scope for this sprint -4. Relevant docs and synchronized artifacts updated or explicitly unchanged: - updated -5. Validation evidence recorded: yes - -Minimum questions to answer: - -1. Is the planned functionality implemented? -2. Are there any known in-scope errors still open? -3. Are the required project quality gates green, including TG001-TG005 checks - when tests changed? -4. Are the relevant docs and synchronized artifacts updated or explicitly unchanged? -5. Is the validation evidence recorded? - -## handoff_note - -1. Finished: the broader `ub-workflow` references, guide, and companion-agent - wording now teach the same Sprint 01 lifecycle. -2. Open: the helper and sprint template still need redesign so the documented - lifecycle becomes mechanically enforced. -3. Next recommended action: start Sprint 03 - Helper And Template Redesign. -4. The next sprint should read this closeout first, then re-open - `./.agents/skills/ub-workflow/references/artifact-contracts.md`, - `./.agents/skills/ub-workflow/references/validation-and-completion.md`, - and `./.agents/skills/ub-workflow/references/scaffold-helper.md`. - -## follow_up_note - -No extra follow-up work was requested during Sprint 02 beyond the planned -Sprint 03 helper and template redesign. Proceed to Sprint 03 next. - -For the final audit sprint, answer at minimum: - -1. Was the user asked whether they want follow-up audits or refactors? -2. Which follow-up items were requested, if any? -3. Which follow-up items were explicitly declined, if any? -4. Did the final validation and documentation synchronization checks pass? -5. Are any governance exceptions, ADR waivers, or follow-up validation items - still open? diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/02-skill-agent-and-reference-alignment/evidence/reference-alignment-summary.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/02-skill-agent-and-reference-alignment/evidence/reference-alignment-summary.md deleted file mode 100644 index 4460623..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/02-skill-agent-and-reference-alignment/evidence/reference-alignment-summary.md +++ /dev/null @@ -1,37 +0,0 @@ -# Sprint 02 Evidence - -## Normalized Lifecycle Summary - -After Sprint 02, the workflow-facing references and guides now teach the same -high-level sequence: - -1. research and discovery -2. self-contained PRD -3. roadmap generation and explicit approval -4. sprint-pack preparation so each `sprint.md` is execution-ready -5. sprint-folder materialization when needed -6. one active sprint at a time -7. final audit -8. retained note and explicit archive decision - -The practical correction is that roadmap approval no longer implies immediate -execution readiness, and `init-sprints` no longer implies that placeholder -shells are acceptable sprint artifacts. - -## User-Facing Resume Order - -The normalized resume order is now: - -1. `./roadmap.md` -2. the most relevant prior sprint `closeout.md` -3. the active or next sprint `sprint.md` -4. `./README.md` -5. `./prd.md` only when initiative-level context is still missing - -## Guidance Versus Enforcement Notes - -1. Sprint-pack preparation is now explicit in the contracts and user guide. -2. The helper guidance now states clearly that current helper commands do not, - by themselves, guarantee execution-ready sprint PRDs. -3. Full helper and template enforcement of that lifecycle remains Sprint 03 - work. diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/02-skill-agent-and-reference-alignment/sprint.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/02-skill-agent-and-reference-alignment/sprint.md deleted file mode 100644 index dcc8111..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/02-skill-agent-and-reference-alignment/sprint.md +++ /dev/null @@ -1,132 +0,0 @@ -# Sprint PRD - -## Summary - -Propagate the new `ub-workflow` lifecycle across every workflow-facing -reference and guide so the system has one coherent story. This sprint makes the -skill, companion agent, artifact contract, validation rules, scaffold -adaptation guidance, scaffold-helper guidance, and user guide all describe the -same sprint-preparation-first workflow instead of leaving the phase model -partially implicit. - -## Scope - -1. Update the artifact contract so `sprint.md` is explicitly an execution-ready - sprint PRD rather than a starter shell. -2. Update the validation and completion contract so `research_ready`, - `sprint_content_ready`, optional `sprint_start_ready`, and final archive - review semantics become explicit readiness checks. -3. Update scaffold-adaptation and scaffold-helper guidance so sprint - preparation is described as a separate phase before sprint materialization or - execution. -4. Update the user guide and broader agent wording so the user-facing story - matches the corrected lifecycle without requiring literal slash commands. - -## Dependencies - -1. Sprint 01 must complete first so the lifecycle and gate model are already - stable before this sprint propagates them. -2. Use the finalized Sprint 01 contract, gate glossary, and session-reset rules - as the authoritative inputs for these documentation and guide changes. -3. Reuse the current `ub-workflow` references and user guide rather than - inventing parallel docs. - -## Repository Truth At Sprint Start - -1. The artifact contract currently says each sprint must stand alone, but the - sprint template and helper behavior have historically allowed placeholder - sprint shells. -2. The validation contract currently treats sprint initialization as the last - planning barrier before execution and does not name a separate - sprint-content-ready phase. -3. Scaffold-adaptation and scaffold-helper guidance currently route users from - roadmap approval to `init-sprints` without a distinct sprint-preparation - step. -4. The user guide still teaches roadmap approval followed by sprint-set - initialization as the immediate path into execution. - -## Chosen Path - -Update the contracts and guides in place so there is one canonical explanation -of the new lifecycle. This keeps the workflow teachable and prevents later -helper or template work from silently redefining behavior that the docs still -describe incorrectly. - -## Rejected Alternative - -Leave the documentation surfaces mostly unchanged and rely on helper behavior -alone to teach the new workflow. - -Pros: - -1. Reduces immediate documentation churn. -2. Keeps the redesign concentrated in scripts. - -Cons: - -1. Leaves contradictory user guidance across the workflow surfaces. -2. Makes the workflow harder to resume correctly after a session reset. -3. Undermines trust because the docs would still teach the old path. - -## Affected Areas - -1. `./.agents/skills/ub-workflow/references/artifact-contracts.md` -2. `./.agents/skills/ub-workflow/references/validation-and-completion.md` -3. `./.agents/skills/ub-workflow/references/scaffold-adaptation.md` -4. `./.agents/skills/ub-workflow/references/scaffold-helper.md` -5. `./.agents/skills/ub-workflow/docs/user-guide.md` -6. `./.github/agents/ub-workflow.agent.md` for the broader wording cleanup - -## Validation Plan - -1. Run `npx --yes markdownlint-cli2` on every touched `ub-workflow` reference, - guide, and agent file. -2. Re-read the touched files in sequence to confirm none of them still imply - that roadmap approval followed by `init-sprints` is sufficient for - execution. -3. Record one normalized lifecycle summary and one user-facing resume order in - `./evidence/` so Sprint 03 can treat those documents as the new reference - surfaces. -4. Record any intentionally deferred wording cleanup in the sprint closeout so - Sprint 03 does not accidentally re-open contract decisions. -5. For the Level 1 `lean` governance bridge, note which workflow requirements - remain guidance versus enforced behavior pending helper changes in Sprint 03. - -## Exit Criteria - -1. All `ub-workflow` contracts and guides describe the same lifecycle, - including sprint preparation before execution. -2. No touched reference or guide still teaches placeholder-only sprint shells - as an acceptable execution state. -3. Sprint closeout gives Sprint 03 a stable documentation and contract baseline - for helper and template redesign. - -## Final Audit Checklist - -Use this checklist only when this sprint is the final audit sprint. - -- [ ] roadmap scope was actually executed or explicitly deferred -- [ ] no material work was silently skipped -- [ ] initiative-level validation is recorded and traceable -- [ ] relevant documentation and synchronized artifacts reflect the shipped behavior -- [ ] follow-up audit or refactor decisions were captured -- [ ] `retained-note.md` is ready to record the final state - -## Handoff Expectation - -Sprint 03 should read this sprint's `closeout.md` first, then re-open the final -artifact and validation contracts. Its first task is to redesign the helper and -sprint template so the lifecycle described in the docs can actually be enforced -in generated initiative output. - -## Definition Of Done - -This sprint is done only when all of the following are true: - -1. planned functionality is complete or explicitly blocked -2. known in-scope issues are documented -3. required validation is run or explicitly deferred -4. relevant documentation and synchronized artifacts are updated or explicitly marked unchanged -5. validation evidence is recorded and traceable -6. governance bridge requirements are satisfied or explicitly marked not applicable -7. closeout is current and resumable diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/03-helper-and-template-redesign/closeout.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/03-helper-and-template-redesign/closeout.md deleted file mode 100644 index 6e44a02..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/03-helper-and-template-redesign/closeout.md +++ /dev/null @@ -1,146 +0,0 @@ -# Sprint Closeout - -## environment_note - -Executed in the local macOS workspace at -`/Users/itechnology/Dev/itech-agents`. Sprint 03 changed the `ub-workflow` -helper implementation, helper regression tests, the canonical sprint template, -and the helper-facing workflow docs and asset guides that describe the new -prepare-sprints behavior. - -## scope_note - -This sprint redesigned the helper and sprint template so roadmap metadata can -become execution-ready sprint PRDs through an explicit `prepare-sprints` -command. It also updated helper-facing docs and asset guides to describe that -new behavior precisely. It did not add the Sprint 04 regression scenarios for -full session-reset or final-audit coverage beyond the targeted helper tests -added here. Governance bridge: `Level 1`, profile `lean`. - -## decision_note - -Chosen path: keep deterministic scaffold operations explicit and conservative, -but add an equally explicit sprint-preparation step that renders roadmap-derived -sprint PRDs before execution begins. - -Rejected alternative: hide deep sprint authoring inside `init-sprints` so one -command both creates directories and silently generates sprint content. - -Pros of the rejected alternative: - -1. Fewer visible commands. -2. Faster path from roadmap approval to generated sprint pack. - -Cons of the rejected alternative: - -1. It blurs the boundary between deterministic scaffold operations and - model-led planning. -2. It makes sprint PRD review harder before execution. -3. It increases the chance that helper behavior and documented lifecycle drift - again. - -## gate_note - -sprint_closeout: pass - -Sprint 03 completed the helper, template, and helper-facing documentation work. -The helper now exposes an explicit `prepare-sprints` command, the roadmap parser -consumes wrapped rich sprint metadata, and the canonical sprint template -separates machine-derived context from human-authored planning. - -confidence: pass - -When governance is active, also record the governance gate type and result as -`merge|confidence|release: pass|fail|blocked`. - -## exception_note - -none - -When governance is active, reference exception records that use the canonical -governance exception metadata. - -## validation_note - -Validation commands and outcomes: - -1. `python -m unittest discover -s .agents/skills/ub-workflow/tests -p 'test_scaffold_initiative.py' -v` - - Result: pass; 12 helper regression tests passed, including the new - `prepare-sprints` coverage for roadmap rendering, preservation of already - prepared sprint docs, and post-roadmap gate advancement. - -1. `python .agents/skills/ub-workflow/scripts/scaffold_initiative.py prepare-sprints --dry-run ./.ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening` - - Result: pass; dry run parsed all 11 live sprint entries with full wrapped - goals, validation focus text, and correct subtask counts. - -1. `npx --yes markdownlint-cli2 .agents/skills/ub-workflow/references/scaffold-helper.md .agents/skills/ub-workflow/references/scaffold-adaptation.md .agents/skills/ub-workflow/docs/user-guide.md .github/agents/ub-workflow.agent.md .agents/skills/ub-workflow/assets/operations-root/user-guide.md .agents/skills/ub-workflow/assets/operations-root/operation-guide.md .agents/skills/ub-workflow/assets/initiative-template/roadmap.md .agents/skills/ub-workflow/assets/initiative-template/sprint-template/sprint.md` - - Result: pass. - -Documentation and synchronized-artifact validation: - -1. `references/scaffold-helper.md` now documents `prepare-sprints` explicitly. -2. `references/scaffold-adaptation.md`, `docs/user-guide.md`, and - `.github/agents/ub-workflow.agent.md` now describe helper-backed sprint-pack - preparation instead of treating it as unavailable. -3. The generated operations-root guides and initiative roadmap template now - teach the new workflow sequence. - -Also record any documentation or synchronized-artifact validation that was required for this sprint. - -When tests changed, record whether TG001-TG005 checks were run and what they -reported. - -When governance is active, record governance-level validation commands, profile, -ADR references, and evidence paths that informed the gate decision. - -## done_verification_note - -Sprint 03 definition of done is satisfied. - -1. Planned functionality implemented: yes -2. Known in-scope errors still open: none within Sprint 03 scope -3. Required quality gates green: yes; helper regression tests, live dry-run - validation, and markdown validation all passed -4. Relevant docs and synchronized artifacts updated or explicitly unchanged: - updated -5. Validation evidence recorded: yes - -Minimum questions to answer: - -1. Is the planned functionality implemented? -2. Are there any known in-scope errors still open? -3. Are the required project quality gates green, including TG001-TG005 checks - when tests changed? -4. Are the relevant docs and synchronized artifacts updated or explicitly unchanged? -5. Is the validation evidence recorded? - -## handoff_note - -1. Finished: the helper now has an explicit `prepare-sprints` phase, the - roadmap parser handles wrapped rich metadata, and the sprint template now - supports execution-ready sprint PRDs. -2. Open: the newly defined parser, pending-handoff behavior, and stop-resume - rules still need fuller regression and resume-scenario protection. -3. Next recommended action: start Sprint 04 - Workflow Regression And Resume - Scenarios. -4. The next sprint should read this closeout first, then inspect - `./.agents/skills/ub-workflow/scripts/scaffold_initiative.py`, - `./.agents/skills/ub-workflow/tests/test_scaffold_initiative.py`, and - `./.agents/skills/ub-workflow/assets/initiative-template/sprint-template/sprint.md`. - -## follow_up_note - -No extra follow-up work was requested during Sprint 03 beyond the planned -Sprint 04 regression and resume-coverage work. Proceed to Sprint 04 next. - -For the final audit sprint, answer at minimum: - -1. Was the user asked whether they want follow-up audits or refactors? -2. Which follow-up items were requested, if any? -3. Which follow-up items were explicitly declined, if any? -4. Did the final validation and documentation synchronization checks pass? -5. Are any governance exceptions, ADR waivers, or follow-up validation items - still open? diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/03-helper-and-template-redesign/evidence/helper-and-template-behavior.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/03-helper-and-template-redesign/evidence/helper-and-template-behavior.md deleted file mode 100644 index 669f003..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/03-helper-and-template-redesign/evidence/helper-and-template-behavior.md +++ /dev/null @@ -1,79 +0,0 @@ -# Sprint 03 Evidence - -## Before And After Sprint Artifact Example - -Before Sprint 03, the canonical sprint template was a generic placeholder shell -with sections such as: - -```md -## Summary - -Replace with the sprint summary. - -## Scope - -1. Replace with the first in-scope item. -2. Replace with the second in-scope item. -``` - -That shape was safe for scaffolding, but it did not turn roadmap data into an -execution-ready sprint PRD. - -After Sprint 03, the template begins with machine-derived context and keeps the -human-authored reasoning sections separate: - -```md -## Machine-Derived Context - -- Sprint: `Sprint 01 - Define Contract` -- Goal: Define the contract so every later sprint inherits one stable workflow baseline -- Depends on: `none` -- Validation focus: Contract review with lifecycle and gate consistency checks -- Evidence folder: `./sprints/01-define-contract/evidence/` -- Planned subtasks: -- [ ] Draft the contract and capture the shared gate vocabulary -- [ ] Review the contract with stakeholders -``` - -The helper now renders that structure from roadmap metadata through the explicit -`prepare-sprints` command. - -## Pending Handoff Marker Semantics - -Allowed pending handoff markers now use the explicit prefix -`PENDING_HANDOFF:`. - -They are reserved for fields that legitimately depend on prior closeout truth, -for example: - -```md -3. PENDING_HANDOFF: Review `Sprint 01 - Define Contract` closeout and carry forward any blockers, validation changes, or repository-truth updates before execution begins. -``` - -Blocking placeholders and pending handoff markers are no longer treated as the -same thing: - -1. `REPLACE_...` and `Replace with ...` remain blocking placeholders. -2. `PENDING_HANDOFF:` is allowed in prepared sprint PRDs when a previous sprint - closeout still needs to flow forward. - -## Deterministic Versus Authored Boundary - -Deterministic helper-owned behavior in Sprint 03: - -1. parse roadmap sprint title, path, goal, dependencies, validation focus, - subtasks, and evidence folder -2. materialize sprint directories when needed -3. render machine-derived sprint context into `sprint.md` -4. preserve already-prepared sprint PRDs that no longer contain blocking - placeholders - -Human- or agent-authored behavior intentionally left outside the helper: - -1. sprint-specific repository truth notes -2. chosen path and rejected alternative analysis -3. affected-area reasoning beyond roadmap metadata -4. sprint-specific validation commands beyond the roadmap baseline - -That boundary preserves conservative deterministic scaffolding while still -producing resumable sprint PRDs before execution begins. diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/03-helper-and-template-redesign/sprint.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/03-helper-and-template-redesign/sprint.md deleted file mode 100644 index 40cc776..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/03-helper-and-template-redesign/sprint.md +++ /dev/null @@ -1,134 +0,0 @@ -# Sprint PRD - -## Summary - -Redesign the workflow helper and sprint template so the corrected lifecycle can -produce execution-ready sprint PRDs instead of generic placeholder shells. This -sprint should keep deterministic scaffold operations conservative, but add an -explicit sprint-preparation phase and the richer roadmap parsing needed to turn -the roadmap into real sprint artifacts before execution starts. - -## Scope - -1. Redesign `roadmap_sprint_entries()` so the helper can extract title, path, - goal, dependencies, validation focus, subtasks, and evidence folder from - the roadmap. -2. Add or model an explicit `prepare-sprints` phase so sprint content can be - authored before execution without hiding deep planning inside - `init-sprints`. -3. Redesign the sprint template so roadmap-derived sections and - human-authored-reasoning sections are clearly separated. -4. Update helper readiness and placeholder logic so blocking machine - placeholders and allowed pending handoff markers are not treated as the same - thing. - -## Dependencies - -1. Sprint 02 must complete first so the helper and template redesign can follow - a stable documented lifecycle and contract surface. -2. Use the current initiative's roadmap and sprint pack as the concrete example - of the failure mode the new helper behavior must solve. -3. Reuse the existing deterministic helper entrypoints where possible instead - of inventing a second workflow system. - -## Repository Truth At Sprint Start - -1. `./.agents/skills/ub-workflow/scripts/scaffold_initiative.py` currently - supports `create`, `init-sprints`, and `archive`, but no explicit - sprint-content-preparation step. -2. The current helper parser extracts only sprint title and path from the - roadmap, not the richer metadata already present in the Sprint Sequence - entries. -3. The current sprint template is a generic placeholder shell rather than a - pre-execution sprint PRD. -4. The current initiative originally proved that rich roadmap data does not, by - itself, guarantee useful sprint PRDs unless the helper or workflow turns - that data into written sprint content. - -## Chosen Path - -Keep deterministic scaffold operations explicit and conservative, but add an -equally explicit sprint-preparation step that authors sprint PRDs from the PRD, -roadmap, and initiative state before execution begins. That preserves review -clarity and makes session-reset recovery depend on written artifacts rather -than regenerated chat reasoning. - -## Rejected Alternative - -Hide deep sprint authoring inside `init-sprints` so one command both creates -directories and silently generates sprint content. - -Pros: - -1. Fewer visible commands. -2. Faster path from roadmap approval to generated sprint pack. - -Cons: - -1. Blurs the boundary between deterministic scaffold operations and model-led - planning. -2. Makes it harder for users to review sprint PRDs before execution. -3. Increases the chance that helper behavior and documented lifecycle will drift - again. - -## Affected Areas - -1. `./.agents/skills/ub-workflow/scripts/scaffold_initiative.py` -2. `./.agents/skills/ub-workflow/assets/initiative-template/sprint-template/sprint.md` -3. Potentially `./.agents/skills/ub-workflow/references/scaffold-helper.md` and - adjacent references where helper behavior must be described precisely -4. The current initiative roadmap and sprint pack as smoke-test targets for the - redesigned helper behavior - -## Validation Plan - -1. Use targeted helper dry runs and controlled generated initiative fixtures to - prove the richer roadmap parser extracts the expected sprint metadata. -2. Run `npx --yes markdownlint-cli2` on the touched template and helper-facing - docs. -3. Record at least one before/after sprint example in `./evidence/` showing a - placeholder-only sprint PRD transformed into an execution-ready one. -4. Record the precise behavior of pending handoff markers so Sprint 04 can turn - it into regression coverage. -5. For the Level 1 `lean` governance bridge, record which parts of the helper - change are deterministic versus model-authored and why that boundary was - chosen. - -## Exit Criteria - -1. The helper and template design support real sprint-content preparation before - execution. -2. The roadmap parser can consume the richer Sprint Sequence metadata already - present in the initiative roadmap. -3. Sprint closeout gives Sprint 04 the exact behaviors that now need - regression-test protection. - -## Final Audit Checklist - -Use this checklist only when this sprint is the final audit sprint. - -- [ ] roadmap scope was actually executed or explicitly deferred -- [ ] no material work was silently skipped -- [ ] initiative-level validation is recorded and traceable -- [ ] relevant documentation and synchronized artifacts reflect the shipped behavior -- [ ] follow-up audit or refactor decisions were captured -- [ ] `retained-note.md` is ready to record the final state - -## Handoff Expectation - -Sprint 04 should read this sprint's `closeout.md` first, then inspect the final -helper behavior and template semantics. Its first task is to convert the newly -defined lifecycle, parser, and placeholder behaviors into deterministic -regression and session-reset resume scenarios. - -## Definition Of Done - -This sprint is done only when all of the following are true: - -1. planned functionality is complete or explicitly blocked -2. known in-scope issues are documented -3. required validation is run or explicitly deferred -4. relevant documentation and synchronized artifacts are updated or explicitly marked unchanged -5. validation evidence is recorded and traceable -6. governance bridge requirements are satisfied or explicitly marked not applicable -7. closeout is current and resumable diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/04-workflow-regression-and-resume-scenarios/closeout.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/04-workflow-regression-and-resume-scenarios/closeout.md deleted file mode 100644 index 0db0b3b..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/04-workflow-regression-and-resume-scenarios/closeout.md +++ /dev/null @@ -1,146 +0,0 @@ -# Sprint Closeout - -## environment_note - -Executed in the local macOS workspace at -`/Users/itechnology/Dev/itech-agents`. Sprint 04 changed the `ub-workflow` -helper implementation and the existing helper regression suite in -`./.agents/skills/ub-workflow/tests/test_scaffold_initiative.py`, then added -Sprint 04 evidence and closeout records plus the initiative state updates. - -## scope_note - -This sprint extended the workflow regression suite to protect the corrected -lifecycle mechanically. It added gating coverage for sprint preparation, -protected the original rich-roadmap but empty-sprint failure mode, added a -later-sprint session-reset resume-order scenario, and blocked archive without -an explicit archive-review or completion gate. It did not start the original -repository-hardening work yet; that remains Sprint 05. Governance bridge: -`Level 1`, profile `lean`. - -## decision_note - -Chosen path: extend the existing workflow test module with scenario-style cases -and a small internal resume-order helper so the corrected lifecycle is covered -by the same helper module and test surface already used in the repository. - -Rejected alternative: rely on manual smoke testing of the redesigned workflow -without expanding the automated regression suite. - -Pros of the rejected alternative: - -1. Lower short-term implementation effort. -2. Fewer fixtures to maintain. - -Cons of the rejected alternative: - -1. It leaves the discovered failure mode free to regress. -2. It makes session-reset resume behavior depend on operator memory. -3. It weakens trust in the workflow redesign because critical behavior would - still be enforced socially rather than mechanically. - -## gate_note - -sprint_closeout: pass - -Sprint 04 completed the planned lifecycle regression work. The workflow test -suite now protects sprint-preparation gating, the placeholder-only sprint -failure mode, later-sprint resume order, and the explicit archive review gate. - -confidence: pass - -When governance is active, also record the governance gate type and result as -`merge|confidence|release: pass|fail|blocked`. - -## exception_note - -none - -When governance is active, reference exception records that use the canonical -governance exception metadata. - -## validation_note - -Validation commands and outcomes: - -1. `python -m unittest discover -s .agents/skills/ub-workflow/tests -p 'test_scaffold_initiative.py' -v` - - Result: pass; 16 workflow helper regression tests passed, including the new - sprint-preparation gating, resume-order, and archive-review cases. - -1. `uv run python -m unittest discover -s .agents/skills/ub-workflow/tests -p 'test_*.py' -v` - - Result: pass; the broader `ub-workflow` test discovery command also passed - with the same 16 tests. - -1. `npx --yes markdownlint-cli2 .ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening/sprints/04-workflow-regression-and-resume-scenarios/closeout.md .ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening/sprints/04-workflow-regression-and-resume-scenarios/evidence/regression-and-resume-coverage.md .ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening/README.md .ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening/roadmap.md` - - Expected final result for this sprint: pass. - -Documentation and synchronized-artifact validation: - -1. No external workflow docs required updates in Sprint 04 because the sprint - focused on regression coverage rather than behavior redesign. -2. The initiative README and roadmap will be updated to show Sprint 04 complete - and Sprint 05 next. - -TG001-TG005 note: - -1. No repository-specific TG001-TG005 workflow exists for this helper suite in - the current repository baseline, so those checks were not separately run. - -Also record any documentation or synchronized-artifact validation that was required for this sprint. - -When tests changed, record whether TG001-TG005 checks were run and what they -reported. - -When governance is active, record governance-level validation commands, profile, -ADR references, and evidence paths that informed the gate decision. - -## done_verification_note - -Sprint 04 definition of done is satisfied. - -1. Planned functionality implemented: yes -2. Known in-scope errors still open: none within Sprint 04 scope -3. Required quality gates green: yes; the targeted workflow suite and the - broader `ub-workflow` test discovery command both passed -4. Relevant docs and synchronized artifacts updated or explicitly unchanged: - updated where needed, otherwise unchanged by design -5. Validation evidence recorded: yes - -Minimum questions to answer: - -1. Is the planned functionality implemented? -2. Are there any known in-scope errors still open? -3. Are the required project quality gates green, including TG001-TG005 checks - when tests changed? -4. Are the relevant docs and synchronized artifacts updated or explicitly unchanged? -5. Is the validation evidence recorded? - -## handoff_note - -1. Finished: the corrected workflow lifecycle is now protected by regression - tests for sprint preparation, resume order, and archive review. -2. Open: the original repository-hardening work has not started yet; the next - sprint can now begin that work on top of the corrected orchestration model. -3. Next recommended action: start Sprint 05 - Inventory Alignment And AGENTS - Rename. -4. The next sprint should read this closeout first, then inspect - `./.agents/skills/ub-workflow/scripts/scaffold_initiative.py` and - `./.agents/skills/ub-workflow/tests/test_scaffold_initiative.py` for the - final workflow baseline. - -## follow_up_note - -No extra follow-up work was requested during Sprint 04 beyond the planned -Sprint 05 repository-hardening work. Proceed to Sprint 05 next. - -For the final audit sprint, answer at minimum: - -1. Was the user asked whether they want follow-up audits or refactors? -2. Which follow-up items were requested, if any? -3. Which follow-up items were explicitly declined, if any? -4. Did the final validation and documentation synchronization checks pass? -5. Are any governance exceptions, ADR waivers, or follow-up validation items - still open? diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/04-workflow-regression-and-resume-scenarios/evidence/regression-and-resume-coverage.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/04-workflow-regression-and-resume-scenarios/evidence/regression-and-resume-coverage.md deleted file mode 100644 index b7f2ef8..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/04-workflow-regression-and-resume-scenarios/evidence/regression-and-resume-coverage.md +++ /dev/null @@ -1,60 +0,0 @@ -# Sprint 04 Evidence - -## Coverage Map - -Sprint 04 extended `test_scaffold_initiative.py` with scenario-style coverage -for the corrected workflow lifecycle. - -New or newly expanded protections: - -1. `test_prepare_sprints_blocks_without_roadmap_approval` - - protects roadmap approval gating before sprint-pack preparation -2. `test_resume_order_for_placeholder_sprint_falls_back_to_prd` - - protects the original rich-roadmap but placeholder-only sprint failure mode -3. `test_resume_order_for_later_prepared_sprint_uses_prior_closeout_without_prd` - - protects later-sprint session-reset resume order -4. `test_archive_blocks_without_archive_review_gate` - - protects the final review pause before archive - -Existing Sprint 03 protections that remain part of the same lifecycle baseline: - -1. `test_prepare_sprints_renders_roadmap_metadata_into_sprint_prds` -2. `test_prepare_sprints_preserves_non_placeholder_sprint_docs` -3. `test_prepare_sprints_accepts_recorded_roadmap_approval_after_gate_advances` - -## Original Failure Mode Regression - -The concrete failure mode discovered in the live initiative was: - -1. `roadmap.md` can be rich and fully planned -2. `init-sprints` can materialize sprint directories -3. the active sprint `sprint.md` can still be a placeholder shell -4. resume or execution then depends on reopening `prd.md` or chat context - -The new regression coverage protects that behavior mechanically: - -1. placeholder-only sprint PRDs now force resume order to include `prd.md` -2. prepared later sprints no longer require `prd.md` when roadmap, prior - closeout, and sprint PRD are sufficient - -## Session-Reset Resume Order - -For a later prepared sprint, the protected minimal resume order is now: - -1. `./roadmap.md` -2. the previous sprint `closeout.md` -3. the active or next sprint `sprint.md` -4. `./README.md` - -`./prd.md` is included only when the sprint PRD is still missing or still -contains blocking placeholders. - -## Archive Review Protection - -Archive is now blocked unless `README.md` records one of: - -1. `archive_ready: pass` -2. `initiative_complete: pass` - -This keeps the final-audit review pause explicit instead of treating a complete -roadmap checklist as sufficient by itself. diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/04-workflow-regression-and-resume-scenarios/sprint.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/04-workflow-regression-and-resume-scenarios/sprint.md deleted file mode 100644 index 194eef8..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/04-workflow-regression-and-resume-scenarios/sprint.md +++ /dev/null @@ -1,125 +0,0 @@ -# Sprint PRD - -## Summary - -Expand `ub-workflow` regression coverage so the corrected lifecycle is enforced -mechanically and the discovered rich-roadmap but empty-sprint failure mode -cannot silently reappear. This sprint turns the redesign work from Sprints 01 -through 03 into scenario-based tests that cover gating, sprint preparation, -session-reset resume order, and final review pauses. - -## Scope - -1. Extend `test_scaffold_initiative.py` with cases for roadmap approval gating, - sprint-content preparation, and refusal to progress when required readiness - checkpoints are missing. -2. Add direct regression coverage for the rich-roadmap but empty-sprint failure - mode that the current initiative exposed. -3. Add at least one session-reset resume scenario for a later sprint, proving - that roadmap plus prior closeout plus active sprint PRD are sufficient to - regain context unless the PRD is genuinely needed. -4. Add final-audit pause and explicit archive-readiness coverage so the review - checkpoint before archive is mechanically protected. - -## Dependencies - -1. Sprint 03 must complete first so the helper and template behaviors under - test are already defined. -2. Use the current initiative's original empty-sprint failure mode and the - redesigned helper behavior as the primary scenario inputs. -3. Reuse and extend `./.agents/skills/ub-workflow/tests/test_scaffold_initiative.py` - before creating any second workflow test suite. - -## Repository Truth At Sprint Start - -1. The existing workflow regression suite currently covers `create`, - `init-sprints`, and `archive`, but it does not yet protect the new - sprint-preparation lifecycle or session-reset resume semantics. -2. The discovered failure mode is concrete and reproducible: the roadmap can be - detailed while sprint PRDs are still placeholder-only. -3. The workflow redesign is not complete until those behaviors are protected by - tests and can fail loudly when they regress. - -## Chosen Path - -Extend the existing workflow test module with scenario-style cases that map -directly to the corrected lifecycle. That keeps regression logic discoverable -and ties the new behavior to the same helper entrypoints and initiative surfaces -already used in the repository. - -## Rejected Alternative - -Rely on manual smoke testing of the redesigned workflow without expanding the -automated regression suite. - -Pros: - -1. Lower short-term implementation effort. -2. Fewer fixtures to maintain. - -Cons: - -1. Leaves the exact discovered failure mode free to regress. -2. Makes session-reset resume behavior a matter of operator memory. -3. Weakens trust in the workflow redesign because the critical behaviors would - still be enforced socially rather than mechanically. - -## Affected Areas - -1. `./.agents/skills/ub-workflow/tests/test_scaffold_initiative.py` -2. Any small workflow fixture inputs needed to model prepared sprint packs, - pending handoff markers, or final-audit states -3. Potentially `./Taskfile.yml` or workflow test wiring only if the new tests - require an updated invocation path - -## Validation Plan - -1. Run `uv run python -m unittest discover -s .agents/skills/ub-workflow/tests - -p 'test_*.py' -v` and record the final output in `./evidence/`. -2. Confirm at least one new regression test would have failed on the original - placeholder-only sprint behavior before the redesign. -3. Confirm at least one resume scenario exercises a later sprint after a - session reset and documents the expected read order. -4. Run `npx --yes markdownlint-cli2` on any touched workflow test-facing docs - or fixtures if they are Markdown-based. -5. For the Level 1 `lean` governance bridge, record the final test coverage map - for lifecycle, placeholder, and archive-review behavior. - -## Exit Criteria - -1. The corrected workflow lifecycle is protected by automated regression tests. -2. The exact discovered failure mode is covered by at least one deterministic - regression case. -3. Sprint closeout gives Sprint 05 an implementation-ready workflow baseline so - the original repository-hardening work can begin under the corrected - orchestration model. - -## Final Audit Checklist - -Use this checklist only when this sprint is the final audit sprint. - -- [ ] roadmap scope was actually executed or explicitly deferred -- [ ] no material work was silently skipped -- [ ] initiative-level validation is recorded and traceable -- [ ] relevant documentation and synchronized artifacts reflect the shipped behavior -- [ ] follow-up audit or refactor decisions were captured -- [ ] `retained-note.md` is ready to record the final state - -## Handoff Expectation - -Sprint 05 should read this sprint's `closeout.md` first, then verify the final -workflow contract, helper behavior, and regression outputs. Its first task is -to begin the original hardening work by aligning the public inventory and -metadata surfaces under the now-corrected `ub-workflow` lifecycle. - -## Definition Of Done - -This sprint is done only when all of the following are true: - -1. planned functionality is complete or explicitly blocked -2. known in-scope issues are documented -3. required validation is run or explicitly deferred -4. relevant documentation and synchronized artifacts are updated or explicitly marked unchanged -5. validation evidence is recorded and traceable -6. governance bridge requirements are satisfied or explicitly marked not applicable -7. closeout is current and resumable diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/05-inventory-alignment-and-agents-rename/closeout.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/05-inventory-alignment-and-agents-rename/closeout.md deleted file mode 100644 index 204b3c7..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/05-inventory-alignment-and-agents-rename/closeout.md +++ /dev/null @@ -1,150 +0,0 @@ -# Sprint Closeout - -## environment_note - -Executed in the local macOS workspace at -`/Users/itechnology/Dev/itech-agents`. Sprint 05 changed the repository root -registry file, public inventory and quick-start documentation, package metadata -surfaces, a small set of skill docs that still referenced `AGENTS.MD`, and the -generated `uv.lock` metadata after the version reconciliation. - -## scope_note - -This sprint aligned the repository's public inventory and metadata surfaces to -verified disk truth. It removed published `Explore` inventory claims while -preserving valid built-in subagent references inside local `.agent.md` files, -completed the root-registry convergence to `AGENTS.md`, and reconciled the -repository version baseline to `1.0.0` across the tracked metadata surfaces. -It did not implement the new integrity validators yet; that remains Sprint 06. -Governance bridge: `Level 1`, profile `lean`. - -## decision_note - -Chosen path: align the human-facing inventory, registry, and version surfaces -first, then let Sprint 06 build validators against that corrected baseline. - -Rejected alternative: build the validators first and let them fail against the -known-misaligned repository state. - -Pros of the rejected alternative: - -1. Drift would become visible immediately. -2. It would produce early failing examples for later regression checks. - -Cons of the rejected alternative: - -1. It would conflate known truth-alignment work with validator defects. -2. It would make failures ambiguous while public surfaces were still known to - be wrong. -3. It would risk encoding stale inventory and filename assumptions into Sprint - 06 validators. - -## gate_note - -sprint_closeout: pass - -Sprint 05 completed the planned truth-alignment work. Public inventory surfaces -now reflect the 4 tracked custom agents on disk, the root registry is -`AGENTS.md`, and the tracked package metadata surfaces now share version -`1.0.0`. - -confidence: pass - -When governance is active, also record the governance gate type and result as -`merge|confidence|release: pass|fail|blocked`. - -## exception_note - -none - -When governance is active, reference exception records that use the canonical -governance exception metadata. - -## validation_note - -Validation commands and outcomes: - -1. `rg -n 'Explore|AGENTS\.MD|AGENTS\.md|"version"|version\s*=' README.md AGENTS.md plugin.json .github/plugin/marketplace.json pyproject.toml .github/agents .agents/skills/ub-css/SKILL.md .agents/skills/ub-python/SKILL.md .agents/skills/ub-ts/SKILL.md .agents/skills/ub-vuejs/SKILL.md .agents/skills/ub-nuxt/SKILL.md .agents/skills/ub-tailwind/SKILL.md uv.lock` - - Result: pass for the intended post-change state. The output showed `AGENTS.md` - on public surfaces, preserved built-in `Explore` references only inside - local `.agent.md` files, and confirmed version `1.0.0` in - `pyproject.toml`, `plugin.json`, `.github/plugin/marketplace.json`, and - `uv.lock`. - -1. `uv lock` - - Result: pass; the lockfile updated the project metadata from `uncle-bob - v0.1.0` to `uncle-bob v1.0.0`. - -1. `npx --yes markdownlint-cli2 AGENTS.md README.md .agents/skills/ub-css/SKILL.md .agents/skills/ub-python/SKILL.md .agents/skills/ub-ts/SKILL.md .agents/skills/ub-vuejs/SKILL.md .agents/skills/ub-nuxt/SKILL.md .agents/skills/ub-tailwind/SKILL.md` - - Result: pass. - -Documentation and synchronized-artifact validation: - -1. `README.md` now teaches `AGENTS.md` in quick-start and repository-layout - text. -2. `AGENTS.md` is now the canonical root registry on disk and no longer lists - `Explore` as a repository custom agent. -3. The touched skill docs now reference `AGENTS.md` instead of `AGENTS.MD` for - centralized version policy. - -Governance bridge note: - -1. No temporary exception was needed. `Explore` remains allowed only as a - built-in subagent reference inside local `.agent.md` files. - -Also record any documentation or synchronized-artifact validation that was required for this sprint. - -When tests changed, record whether TG001-TG005 checks were run and what they -reported. - -When governance is active, record governance-level validation commands, profile, -ADR references, and evidence paths that informed the gate decision. - -## done_verification_note - -Sprint 05 definition of done is satisfied. - -1. Planned functionality implemented: yes -2. Known in-scope errors still open: none within Sprint 05 scope -3. Required quality gates green: yes; the grep-based surface check, - `uv lock`, and markdown validation all passed -4. Relevant docs and synchronized artifacts updated or explicitly unchanged: - updated -5. Validation evidence recorded: yes - -Minimum questions to answer: - -1. Is the planned functionality implemented? -2. Are there any known in-scope errors still open? -3. Are the required project quality gates green, including TG001-TG005 checks - when tests changed? -4. Are the relevant docs and synchronized artifacts updated or explicitly unchanged? -5. Is the validation evidence recorded? - -## handoff_note - -1. Finished: public inventory, root-registry naming, and version metadata now - match the intended repository baseline. -2. Open: repository integrity validators still need to encode this aligned - truth into deterministic checks. -3. Next recommended action: start Sprint 06 - Repository Integrity Validators. -4. The next sprint should read this closeout first, then re-read `./AGENTS.md`, - `./README.md`, `./plugin.json`, `./.github/plugin/marketplace.json`, and - `./pyproject.toml` before implementing the validators. - -## follow_up_note - -No extra follow-up work was requested during Sprint 05 beyond the planned -Sprint 06 validator work. Proceed to Sprint 06 next. - -For the final audit sprint, answer at minimum: - -1. Was the user asked whether they want follow-up audits or refactors? -2. Which follow-up items were requested, if any? -3. Which follow-up items were explicitly declined, if any? -4. Did the final validation and documentation synchronization checks pass? -5. Are any governance exceptions, ADR waivers, or follow-up validation items - still open? diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/05-inventory-alignment-and-agents-rename/evidence/.gitkeep b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/05-inventory-alignment-and-agents-rename/evidence/.gitkeep deleted file mode 100644 index 2fa992c..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/05-inventory-alignment-and-agents-rename/evidence/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -keep diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/05-inventory-alignment-and-agents-rename/evidence/inventory-and-metadata-alignment.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/05-inventory-alignment-and-agents-rename/evidence/inventory-and-metadata-alignment.md deleted file mode 100644 index 14dc31c..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/05-inventory-alignment-and-agents-rename/evidence/inventory-and-metadata-alignment.md +++ /dev/null @@ -1,58 +0,0 @@ -# Sprint 05 Evidence - -## Inventory Alignment Result - -Verified on-disk custom agents under `./.github/agents/`: - -1. `ub-customizations.agent.md` -2. `ub-governance.agent.md` -3. `ub-teacher.agent.md` -4. `ub-workflow.agent.md` - -Published repository inventory now matches that disk truth: - -1. `README.md` lists 4 custom agents and no longer publishes `Explore` as a - repository agent. -2. `AGENTS.md` lists the same 4 custom agents and no longer publishes - `Explore` as a repository agent. -3. `.github/plugin/marketplace.json` now describes `4 custom agents` instead - of `5 agents` and no longer counts `explore` as a repository agent. - -Built-in subagent references were preserved where they remain legitimate local -implementation details: - -1. `agents: ["Explore"]` in local `.agent.md` files -2. explanatory text that delegates read-only exploration to the built-in - `Explore` subagent - -## Root Registry Filename Result - -The root registry file is now `./AGENTS.md` on disk. - -The rename required a case-only filesystem-safe transition through a temporary -filename so the repository would no longer preserve the legacy `AGENTS.MD` -entry on the default macOS filesystem. - -Updated public references now point to `AGENTS.md`: - -1. quick-start copy and symlink commands in `README.md` -2. repository layout text in `README.md` -3. centralized version-policy references in the touched skill files - -## Version Reconciliation Result - -The chosen repository version baseline is now `1.0.0` across the tracked -metadata surfaces: - -1. `pyproject.toml`: `1.0.0` -2. `plugin.json`: `1.0.0` -3. `.github/plugin/marketplace.json`: `1.0.0` - -`uv lock` was rerun so `uv.lock` now records the same project version. - -## Temporary Exception Result - -No temporary exception was needed. - -`Explore` remains valid only as a built-in subagent reference inside local -agent definitions, not as a published repository custom agent. diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/05-inventory-alignment-and-agents-rename/sprint.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/05-inventory-alignment-and-agents-rename/sprint.md deleted file mode 100644 index 6a76248..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/05-inventory-alignment-and-agents-rename/sprint.md +++ /dev/null @@ -1,138 +0,0 @@ -# Sprint PRD - -## Summary - -Align the repository's public inventory and metadata surfaces with verified -disk truth before any repository-wide checker work begins. This sprint removes -published `Explore` agent inventory claims while preserving valid built-in -subagent references, converges the root registry path from `AGENTS.MD` to -`AGENTS.md`, and reconciles version drift across the packaging surfaces so -later validators have one trustworthy baseline to enforce. - -## Scope - -1. Remove `Explore` from published repository agent inventory and count claims - while preserving legitimate built-in subagent references inside local - `.agent.md` files. -2. Rename the root registry file from `AGENTS.MD` to `AGENTS.md` and update all - canonical references, quick-start instructions, and repository-layout text. -3. Reconcile version drift across `./pyproject.toml`, `./plugin.json`, and - `./.github/plugin/marketplace.json`. -4. Record any explicit temporary exception needed so Sprint 02 can treat the - aligned public surfaces as authoritative. - -## Dependencies - -1. Sprint 04 must complete first so the workflow redesign, helper behavior, and - sprint-preparation regression coverage are already stable before the original - hardening work begins. -2. Use `./prd.md` section 25 as the verified contract source for `AGENTS.md`, - built-in-versus-workspace agent behavior, and the current metadata-drift - facts. -3. Use tracked disk truth from `./.agents/skills/`, `./.github/agents/`, - `./README.md`, `./plugin.json`, `./.github/plugin/marketplace.json`, - `./pyproject.toml`, and `./AGENTS.MD`. - -## Repository Truth At Sprint Start - -1. The root registry file on disk is currently `./AGENTS.MD`, while the PRD - and verification addendum treat `AGENTS.md` as the intended canonical - standard. -2. `./README.md` currently lists `Explore` in the public agent inventory even - though only four tracked `.agent.md` files exist under `./.github/agents/`. -3. `./plugin.json` and `./.github/plugin/marketplace.json` currently report - version `1.0.0`, while `./pyproject.toml` reports `0.1.0`. -4. `./README.md` quick-start and repository-layout instructions currently refer - to `AGENTS.MD`. -5. Sprint 06 assumes these public surfaces are aligned before new repository - integrity validators are introduced. - -## Chosen Path - -Align the human-facing surfaces first, then build validators against the -corrected baseline. That keeps Sprint 02 focused on durable enforcement instead -of mixing product-surface fixes with validation logic and avoids encoding known -wrong inventory or filename claims into new checker expectations. - -## Rejected Alternative - -Build the validators first and let them fail against the current repository. - -Pros: - -1. Forces drift to become visible immediately. -2. Produces early failing examples for future regression tests. - -Cons: - -1. Conflates known truth-alignment work with validator implementation. -2. Makes it harder to tell whether a failure is a real checker defect or an - intentionally unfixed public-surface mismatch. -3. Risks baking stale inventory and filename assumptions into Sprint 06. - -## Affected Areas - -1. `./AGENTS.MD` or its renamed successor `./AGENTS.md` -2. `./README.md` -3. `./plugin.json` -4. `./.github/plugin/marketplace.json` -5. `./pyproject.toml` -6. `./.github/agents/*.agent.md` only when built-in subagent wording must stay - explicit after `Explore` is removed from published inventory surfaces - -## Validation Plan - -1. Use targeted repository scans such as - `rg -n "Explore|AGENTS\\.MD|AGENTS\\.md|\"version\"" README.md AGENTS.MD AGENTS.md plugin.json .github/plugin/marketplace.json pyproject.toml .github/agents` to confirm the before and after state. -2. Run `npx --yes markdownlint-cli2 README.md AGENTS.md` after the registry - rename and public-doc updates. -3. Re-open `./plugin.json`, `./.github/plugin/marketplace.json`, and - `./pyproject.toml` to verify the chosen version string is identical in all - three surfaces. -4. Record before/after inventory counts and the resolved root-registry filename - in `./evidence/` so Sprint 02 can treat the aligned surfaces as the new - baseline. -5. For the Level 1 `lean` governance bridge, record any deliberate temporary - exception or deferral in the sprint closeout instead of leaving it implicit. - -## Exit Criteria - -1. Public inventory and quick-start surfaces match current disk truth, - including removal of published `Explore` inventory claims and convergence on - `AGENTS.md`. -2. Version metadata is reconciled across the three packaging surfaces or any - deliberate exception is explicitly recorded. -3. Sprint closeout names the aligned surfaces that Sprint 06 should now treat - as authoritative. - -## Final Audit Checklist - -Use this checklist only when this sprint is the final audit sprint. - -- [ ] roadmap scope was actually executed or explicitly deferred -- [ ] no material work was silently skipped -- [ ] initiative-level validation is recorded and traceable -- [ ] relevant documentation and synchronized artifacts reflect the shipped behavior -- [ ] follow-up audit or refactor decisions were captured -- [ ] `retained-note.md` is ready to record the final state - -## Handoff Expectation - -Sprint 06 should read this sprint's `closeout.md` first, then re-read -`./AGENTS.md`, `./README.md`, `./plugin.json`, -`./.github/plugin/marketplace.json`, and `./pyproject.toml` before creating -the repository integrity scripts. Its first task is to encode the aligned disk -and metadata truth into deterministic low-noise validators under -`./.agents/skills/ub-governance/scripts/`. - -## Definition Of Done - -This sprint is done only when all of the following are true: - -1. planned functionality is complete or explicitly blocked -2. known in-scope issues are documented -3. required validation is run or explicitly deferred -4. relevant documentation and synchronized artifacts are updated or explicitly marked unchanged -5. validation evidence is recorded and traceable -6. governance bridge requirements are satisfied or explicitly marked not applicable -7. closeout is current and resumable diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/06-repo-integrity-validators/closeout.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/06-repo-integrity-validators/closeout.md deleted file mode 100644 index 04d2ac8..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/06-repo-integrity-validators/closeout.md +++ /dev/null @@ -1,171 +0,0 @@ -# Sprint Closeout - -## environment_note - -Executed in the local macOS workspace at -`/Users/itechnology/Dev/itech-agents`. Sprint 06 changed the -`ub-governance` checker scripts, the shared governance-script regression suite, -and the governance-skill integrity requirements so the new repository-wide -validators are treated as first-class governance assets. - -## scope_note - -This sprint added the repository-wide integrity baseline under -`ub-governance`: catalog validation, package metadata validation, exact path and -case validation, and skill frontmatter/runtime-reference validation. It also -encoded the low-noise ignore-scope decision so `tmp/` and other fixture-like -content remain outside the default authoritative scan scope. It did not wire the -new commands into `Taskfile.yml` or CI; that remains Sprint 07. Governance -bridge: `Level 1`, profile `lean`. - -## decision_note - -Chosen path: add four focused CLI scripts under `ub-governance` plus a very -small shared helper for repo walking and parsing, while keeping each validator -independently executable under `uv run python`. - -Rejected alternative: build one monolithic repository checker for catalog, -metadata, paths, and skill schema in a single script. - -Pros of the rejected alternative: - -1. One entrypoint is easy to discover. -2. Shared logic is trivial when everything lives in one file. - -Cons of the rejected alternative: - -1. Failures are harder to localize. -2. Sprint 07 CI and Taskfile wiring would be coarser than necessary. -3. The checker would be harder to test and more likely to grow into an - over-coupled subsystem. - -## gate_note - -sprint_closeout: pass - -Sprint 06 completed the planned repository-integrity baseline. The repository -now has focused deterministic validators for catalog integrity, package -metadata, exact path/case correctness, and skill frontmatter/runtime-reference -validity, with direct CLI proof and regression coverage. - -confidence: pass - -When governance is active, also record the governance gate type and result as -`merge|confidence|release: pass|fail|blocked`. - -## exception_note - -none - -When governance is active, reference exception records that use the canonical -governance exception metadata. - -## validation_note - -Validation commands and outcomes: - -1. `uv run python .agents/skills/ub-governance/scripts/check_repo_catalog.py` - - Result: pass on the live repository. - -1. `uv run python .agents/skills/ub-governance/scripts/check_package_metadata.py` - - Result: pass on the live repository. - -1. `uv run python .agents/skills/ub-governance/scripts/check_repo_paths.py` - - Result: pass on the live repository. - -1. `uv run python .agents/skills/ub-governance/scripts/check_skill_schema.py` - - Result: pass on the live repository. - -1. `uv run python .agents/skills/ub-governance/scripts/check_skill_integrity.py` - - Result: pass after registering the new scripts as required governance - assets. - -1. `uv run python -m unittest discover -s .agents/skills/ub-governance/tests/governance_scripts -p 'test_*.py' -v` - - Result: pass; 14 governance script regression tests passed, including pass - and fail coverage for each new repository-integrity validator. - -Documentation and synchronized-artifact validation: - -1. No public repository docs were updated in Sprint 06 because this sprint - introduced enforcement scripts and tests rather than a new public-facing - contract. -2. `check_skill_integrity.py` was updated so the new validators are now part of - the enforced ub-governance asset baseline. - -TG001-TG005 note: - -1. No separate TG001-TG005 project test run was needed for Sprint 06 because - the work was limited to governance validator scripts and their regression - suite. The existing `check_test_signal.py` regression coverage remained - green inside the governance test module. - -Governance-level validation note: - -1. Profile: `lean` -2. Authoritative surfaces enforced by the new baseline: `AGENTS.md`, - `README.md`, `plugin.json`, `.github/plugin/marketplace.json`, - `pyproject.toml`, `.agents/skills/`, and `.github/agents/` -3. Default ignored scope: `tmp/` and fixture-like content outside canonical - authoritative roots - -Also record any documentation or synchronized-artifact validation that was required for this sprint. - -When tests changed, record whether TG001-TG005 checks were run and what they -reported. - -When governance is active, record governance-level validation commands, profile, -ADR references, and evidence paths that informed the gate decision. - -## done_verification_note - -Sprint 06 definition of done is satisfied. - -1. Planned functionality implemented: yes -2. Known in-scope errors still open: none within Sprint 06 scope -3. Required quality gates green: yes; all 4 new validators passed on the live - repository, `check_skill_integrity.py` passed, and the governance regression - suite passed -4. Relevant docs and synchronized artifacts updated or explicitly unchanged: - unchanged by design except for sprint records and governance script assets -5. Validation evidence recorded: yes - -Minimum questions to answer: - -1. Is the planned functionality implemented? -2. Are there any known in-scope errors still open? -3. Are the required project quality gates green, including TG001-TG005 checks - when tests changed? -4. Are the relevant docs and synchronized artifacts updated or explicitly unchanged? -5. Is the validation evidence recorded? - -## handoff_note - -1. Finished: the repository now has stable direct-CLI integrity validators and - regression coverage for catalog, metadata, path, and skill-schema checks. -2. Open: local task wiring and CI parity still need to be added for the new - validators. -3. Next recommended action: start Sprint 07 - CI Parity And Regression - Coverage. -4. The next sprint should read this closeout first, then inspect the final - scripts under `./.agents/skills/ub-governance/scripts/` and the regression - suite in `./.agents/skills/ub-governance/tests/governance_scripts/`. - -## follow_up_note - -No extra follow-up work was requested during Sprint 06 beyond the planned -Sprint 07 Taskfile and CI parity work. Proceed to Sprint 07 next. - -For the final audit sprint, answer at minimum: - -1. Was the user asked whether they want follow-up audits or refactors? -2. Which follow-up items were requested, if any? -3. Which follow-up items were explicitly declined, if any? -4. Did the final validation and documentation synchronization checks pass? -5. Are any governance exceptions, ADR waivers, or follow-up validation items - still open? diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/06-repo-integrity-validators/evidence/.gitkeep b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/06-repo-integrity-validators/evidence/.gitkeep deleted file mode 100644 index 2fa992c..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/06-repo-integrity-validators/evidence/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -keep diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/06-repo-integrity-validators/evidence/repo-integrity-validator-baseline.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/06-repo-integrity-validators/evidence/repo-integrity-validator-baseline.md deleted file mode 100644 index 8d407c7..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/06-repo-integrity-validators/evidence/repo-integrity-validator-baseline.md +++ /dev/null @@ -1,83 +0,0 @@ -# Sprint 06 Evidence - -## Added Validator Entry Points - -Sprint 06 added these focused CLI validators under -`./.agents/skills/ub-governance/scripts/`: - -1. `check_repo_catalog.py` -2. `check_package_metadata.py` -3. `check_repo_paths.py` -4. `check_skill_schema.py` - -Shared helper surface introduced for low-duplication repo walking and parsing: - -1. `._repo_integrity.py` - -The existing governance integrity checker now treats the 4 new validator -scripts as required governance assets. - -## Authoritative Surface Baseline - -Sprint 06 encodes this authoritative default repository baseline: - -1. root registry: `./AGENTS.md` -2. public overview: `./README.md` -3. package metadata: `./plugin.json` -4. marketplace metadata: `./.github/plugin/marketplace.json` -5. Python package metadata: `./pyproject.toml` -6. custom agent root: `./.github/agents/` -7. skill root: `./.agents/skills/` - -Low-noise default ignore scope: - -1. `./tmp/` -2. fixture-like test content outside the canonical authoritative roots above - -## Direct CLI Proof - -These commands passed against the live repository: - -1. `uv run python .agents/skills/ub-governance/scripts/check_repo_catalog.py` -2. `uv run python .agents/skills/ub-governance/scripts/check_package_metadata.py` -3. `uv run python .agents/skills/ub-governance/scripts/check_repo_paths.py` -4. `uv run python .agents/skills/ub-governance/scripts/check_skill_schema.py` -5. `uv run python .agents/skills/ub-governance/scripts/check_skill_integrity.py` - -Observed pass-state highlights: - -1. `check_repo_catalog.py` confirmed 10 tracked skills and 4 tracked custom - agents across disk, `AGENTS.md`, and `README.md` while allowing curated - table ordering. -2. `check_package_metadata.py` confirmed version `1.0.0` across - `pyproject.toml`, `plugin.json`, and `.github/plugin/marketplace.json`, and - confirmed the marketplace description claim of 10 skills and 4 custom - agents. -3. `check_repo_paths.py` confirmed exact-case canonical paths, including the - root `AGENTS.md` rename. -4. `check_skill_schema.py` confirmed valid frontmatter and local reference - resolution across the 10 tracked skills. - -## Regression Coverage Map - -`test_governance_scripts.py` now covers pass and fail behavior for each new -validator: - -1. catalog pass with `tmp/` noise ignored -2. catalog fail on README inventory drift -3. package-metadata pass with aligned versions and count claims -4. package-metadata fail with version and count drift -5. path pass with exact case and `tmp/` noise ignored -6. path fail with legacy `AGENTS.MD` -7. skill-schema pass with valid frontmatter and references -8. skill-schema fail with invalid frontmatter and missing local references - -## Sprint 07 Wiring Targets - -Sprint 07 should wire these stable commands into `Taskfile.yml` and CI: - -1. `uv run python .agents/skills/ub-governance/scripts/check_repo_catalog.py` -2. `uv run python .agents/skills/ub-governance/scripts/check_package_metadata.py` -3. `uv run python .agents/skills/ub-governance/scripts/check_repo_paths.py` -4. `uv run python .agents/skills/ub-governance/scripts/check_skill_schema.py` -5. `uv run python -m unittest discover -s .agents/skills/ub-governance/tests/governance_scripts -p 'test_*.py' -v` diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/06-repo-integrity-validators/sprint.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/06-repo-integrity-validators/sprint.md deleted file mode 100644 index ed78b49..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/06-repo-integrity-validators/sprint.md +++ /dev/null @@ -1,144 +0,0 @@ -# Sprint PRD - -## Summary - -Build the repository-wide integrity baseline under `ub-governance` after Sprint -01 aligns the public inventory and metadata surfaces. This sprint should add -deterministic, low-noise validators for repository catalog integrity, package -metadata consistency, exact path and case correctness, and minimal skill -schema/runtime-reference validity, while preserving the existing direct-CLI -script pattern already used in `ub-governance`. - -## Scope - -1. Implement `check_repo_catalog.py` for disk-versus-registry comparison across - skills, custom agents, the root registry, README inventory tables, and - package metadata surfaces. -2. Implement `check_package_metadata.py` for version and inventory-like claim - validation across `./plugin.json` and - `./.github/plugin/marketplace.json`. -3. Implement `check_repo_paths.py` for exact tracked path and case validation - across canonical repository surfaces. -4. Implement `check_skill_schema.py` plus any minimal schema asset needed to - validate skill frontmatter shape and runtime-facing reference paths. -5. Define the low-noise ignore-scope behavior so `./tmp/`, fixtures, and other - non-authoritative content stay excluded by default. - -## Dependencies - -1. Sprint 05 must finish first so the public inventory, canonical filename, and - version metadata are aligned before the new validators are authored. -2. Use `./prd.md` sections 11.1 through 11.4, section 17 phase 1, section 18 - actions 1 through 4, and section 25 derived planning decisions as the - product contract for the baseline checker suite. -3. Reuse the existing direct-CLI validation pattern already present in - `./.agents/skills/ub-governance/scripts/check_skill_integrity.py` and the - subprocess-style regression approach already used in the governance test - suite. - -## Repository Truth At Sprint Start - -1. `./.agents/skills/ub-governance/scripts/` already contains focused CLI - validators such as `check_skill_integrity.py`, `check_claim_register.py`, - and `check_test_signal.py`. -2. `./.agents/skills/ub-governance/tests/governance_scripts/` already provides - the current subprocess-style regression-test pattern for governance scripts. -3. `./.agents/skills/` currently contains ten tracked skills and - `./.github/agents/` currently contains four tracked custom agent - definitions. -4. `./tmp/` and other fixture-like content must remain outside the default - authoritative scan scope or the new checkers will become noisy and lose - trust. -5. No repository-wide checker suite currently validates all of the canonical - public inventory, metadata, path, and skill-reference surfaces together. - -## Chosen Path - -Implement four focused CLI scripts under `./.agents/skills/ub-governance/scripts/` -using the existing house pattern, and introduce only the smallest shared helper -surface that remains safe for direct script execution under `uv run python`. -This keeps the baseline explicit, debuggable, and composable while still -reducing duplicated repo-walking and UTF-8 parsing logic when duplication would -otherwise be substantial. - -## Rejected Alternative - -Create one monolithic repository checker that handles catalog, metadata, paths, -and skill schema in a single large script. - -Pros: - -1. One entrypoint is easy to discover. -2. Shared logic is trivial because everything lives in one file. - -Cons: - -1. Failures become harder to localize and reason about. -2. Future CI and Taskfile parity work becomes coarser than necessary. -3. The script would be harder to test and more likely to grow into an - over-coupled governance subsystem. - -## Affected Areas - -1. `./.agents/skills/ub-governance/scripts/` -2. `./.agents/skills/ub-governance/tests/governance_scripts/` -3. `./.agents/skills/ub-governance/references/skill-frontmatter.schema.json` - if a dedicated schema artifact is introduced -4. `./AGENTS.md`, `./README.md`, `./plugin.json`, - `./.github/plugin/marketplace.json`, and `./.agents/skills/*/SKILL.md` as - validated inputs rather than as primary implementation surfaces - -## Validation Plan - -1. Run each new script directly with `uv run python` to confirm it is - executable as a standalone CLI without relying on package installation. -2. Run `uv run python -m unittest discover -s - .agents/skills/ub-governance/tests/governance_scripts -p 'test_*.py' -v` - after adding regression coverage for pass and fail cases. -3. Use fixture inputs or temporary repositories to prove that `./tmp/` and - other non-authoritative surfaces are ignored by default. -4. Record example pass/fail outputs for the four new scripts in `./evidence/` - so Sprint 07 can wire the exact commands into local and CI parity work. -5. For the Level 1 `lean` governance bridge, document the final authoritative - surface list and ignore-scope decision in the sprint closeout. - -## Exit Criteria - -1. The repository has focused baseline checkers for catalog integrity, package - metadata, path/case correctness, and skill schema/runtime-reference - validity. -2. Each checker has direct CLI execution proof and regression-test coverage for - at least one pass and one fail case. -3. Sprint closeout names the stable script interfaces and commands Sprint 07 - should wire into Taskfile and CI parity. - -## Final Audit Checklist - -Use this checklist only when this sprint is the final audit sprint. - -- [ ] roadmap scope was actually executed or explicitly deferred -- [ ] no material work was silently skipped -- [ ] initiative-level validation is recorded and traceable -- [ ] relevant documentation and synchronized artifacts reflect the shipped behavior -- [ ] follow-up audit or refactor decisions were captured -- [ ] `retained-note.md` is ready to record the final state - -## Handoff Expectation - -Sprint 07 should read this sprint's `closeout.md` first, then inspect the final -CLI entrypoints and test locations under `./.agents/skills/ub-governance/`. -Its first task is to wire the new checker commands into `./Taskfile.yml`, -extend `./.github/workflows/quality.yml`, and add any missing regression -fixtures so local `task check` is the closest parity mirror of CI. - -## Definition Of Done - -This sprint is done only when all of the following are true: - -1. planned functionality is complete or explicitly blocked -2. known in-scope issues are documented -3. required validation is run or explicitly deferred -4. relevant documentation and synchronized artifacts are updated or explicitly marked unchanged -5. validation evidence is recorded and traceable -6. governance bridge requirements are satisfied or explicitly marked not applicable -7. closeout is current and resumable diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/07-ci-parity-and-regression-coverage/closeout.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/07-ci-parity-and-regression-coverage/closeout.md deleted file mode 100644 index 0f6635a..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/07-ci-parity-and-regression-coverage/closeout.md +++ /dev/null @@ -1,182 +0,0 @@ -# Sprint Closeout - -## environment_note - -Executed in the local macOS workspace at -`/Users/itechnology/Dev/itech-agents`. Sprint 07 changed the root `Taskfile.yml`, -the GitHub Actions quality workflow, the governance regression suite, static -governance fixture trees, markdownlint scope configuration, and a small -ub-workflow helper cleanup needed so repo-wide `task check` could pass. - -## scope_note - -This sprint aligned local and CI quality coverage for the repository-integrity, -governance, and workflow checks. It added first-class Task targets for the new -integrity validators, extended the quality workflow to run workflow regression -and each repository-integrity check, and added static pass/fail fixtures for -inventory drift, metadata drift, path-case mismatch, broken skill references, -and ignored `tmp/` behavior. It did not implement new placeholder validation; -that remains Sprint 08. Governance bridge: `Level 1`, profile `lean`. - -## decision_note - -Chosen path: extend the existing Taskfile and quality workflow in place, then -back the new integrity drift cases with static repo fixtures so local and CI -parity can run through the same visible commands. - -Rejected alternative: document the new validator commands but defer Taskfile, -CI, and fixture parity until a later sprint. - -Pros of the rejected alternative: - -1. Less immediate workflow churn. -2. Less upfront fixture work. - -Cons of the rejected alternative: - -1. It would keep local and CI behavior out of sync at the point where the - integrity surface just expanded. -2. It would make the new regression coverage optional instead of structural. -3. It would violate the roadmap's explicit parity objective. - -## gate_note - -sprint_closeout: pass - -Sprint 07 completed the parity wiring. `task check` is now a green local mirror -for the authoritative CI lint, integrity, governance, and workflow surfaces, -and the quality workflow runs the same integrity and workflow commands through -its matrix. - -confidence: pass - -When governance is active, also record the governance gate type and result as -`merge|confidence|release: pass|fail|blocked`. - -## exception_note - -none - -When governance is active, reference exception records that use the canonical -governance exception metadata. - -## validation_note - -Validation commands and outcomes: - -1. `uv run python -m unittest discover -s .agents/skills/ub-governance/tests/governance_scripts -p 'test_*.py' -v` - - Result: pass; governance regression coverage stayed green after moving the - repository-integrity cases onto static fixture trees. - -2. `task test-repo-catalog` - - Result: pass. - -3. `task test-package-metadata` - - Result: pass. - -4. `task test-repo-paths` - - Result: pass. - -5. `task test-skill-schema` - - Result: pass. - -6. `task test-governance-integrity` - - Result: pass. - -7. `task test-governance` - - Result: pass. - -8. `task test-workflow` - - Result: pass. - -9. `task check` - - Result: pass; local parity now covers authoritative markdown lint, Python - lint, YAML lint, integrity checks, governance regression, and workflow - regression through one aggregate entrypoint. - -Documentation and synchronized-artifact validation: - -1. `Taskfile.yml` now exposes the new integrity tasks and keeps `check` as the - aggregate parity entrypoint. -2. `.github/workflows/quality.yml` now includes workflow regression and the - repository-integrity targets in the existing matrix pattern. -3. Lint scope was tightened to authoritative markdown and YAML surfaces so - scratch `tmp/` content and repo-snapshot fixtures do not create parity noise. - -TG001-TG005 note: - -1. No separate TG001-TG005 project test run was needed. The sprint changed - governance and workflow regression wiring rather than product behavior, and - both regression suites passed through the final parity commands. - -Governance-level validation note: - -1. Profile: `lean` -2. Final local-to-CI parity contract: markdown lint, Python lint, YAML lint, - repository-integrity checks, governance regression, and workflow regression -3. Evidence path: `./evidence/ci-parity-and-fixture-coverage.md` - -Also record any documentation or synchronized-artifact validation that was required for this sprint. - -When tests changed, record whether TG001-TG005 checks were run and what they -reported. - -When governance is active, record governance-level validation commands, profile, -ADR references, and evidence paths that informed the gate decision. - -## done_verification_note - -Sprint 07 definition of done is satisfied. - -1. Planned functionality implemented: yes -2. Known in-scope errors still open: none within Sprint 07 scope -3. Required quality gates green: yes; `task check` passed after Taskfile, CI, - fixture, and lint-scope parity work landed -4. Relevant docs and synchronized artifacts updated or explicitly unchanged: - updated -5. Validation evidence recorded: yes - -Minimum questions to answer: - -1. Is the planned functionality implemented? -2. Are there any known in-scope errors still open? -3. Are the required project quality gates green, including TG001-TG005 checks - when tests changed? -4. Are the relevant docs and synchronized artifacts updated or explicitly unchanged? -5. Is the validation evidence recorded? - -## handoff_note - -1. Finished: Taskfile and CI now run the repository-integrity, governance, and - workflow baselines through aligned authoritative targets, and static - repo-integrity fixtures back the high-value drift cases. -2. Open: placeholder-completeness validation for generated initiative - artifacts still needs to be defined and implemented. -3. Next recommended action: start Sprint 08 - Workflow Placeholder Hardening. -4. The next sprint should read this closeout first, then inspect `Taskfile.yml`, - `.github/workflows/quality.yml`, the repo-integrity fixtures under - `./.agents/skills/ub-governance/tests/governance_scripts/fixtures/repo_integrity/`, - and the workflow regression suite. - -## follow_up_note - -No extra follow-up work was requested during Sprint 07 beyond the planned -Sprint 08 placeholder-hardening work. Proceed to Sprint 08 next. - -For the final audit sprint, answer at minimum: - -1. Was the user asked whether they want follow-up audits or refactors? -2. Which follow-up items were requested, if any? -3. Which follow-up items were explicitly declined, if any? -4. Did the final validation and documentation synchronization checks pass? -5. Are any governance exceptions, ADR waivers, or follow-up validation items - still open? diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/07-ci-parity-and-regression-coverage/evidence/.gitkeep b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/07-ci-parity-and-regression-coverage/evidence/.gitkeep deleted file mode 100644 index 2fa992c..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/07-ci-parity-and-regression-coverage/evidence/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -keep diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/07-ci-parity-and-regression-coverage/evidence/ci-parity-and-fixture-coverage.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/07-ci-parity-and-regression-coverage/evidence/ci-parity-and-fixture-coverage.md deleted file mode 100644 index 83f98be..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/07-ci-parity-and-regression-coverage/evidence/ci-parity-and-fixture-coverage.md +++ /dev/null @@ -1,82 +0,0 @@ -# Sprint 07 Evidence - -## Taskfile Parity Mapping - -Sprint 07 added first-class Task targets for each repository-integrity checker: - -1. `task test-repo-catalog` -2. `task test-package-metadata` -3. `task test-repo-paths` -4. `task test-skill-schema` -5. `task test-governance-integrity` - -Aggregate parity targets after Sprint 07: - -1. `task test-integrity` runs the 5 integrity targets above. -2. `task test-governance` runs the governance script regression suite. -3. `task test-workflow` runs the ub-workflow scaffold regression suite. -4. `task check` now runs authoritative markdown lint, Python lint, YAML lint, - all integrity checks, the governance regression suite, and the workflow - regression suite. - -## CI Parity Mapping - -`.github/workflows/quality.yml` now runs these Python-quality matrix targets: - -1. `lint-py` -2. `lint-yaml` -3. `test-repo-catalog` -4. `test-package-metadata` -5. `test-repo-paths` -6. `test-skill-schema` -7. `test-governance-integrity` -8. `test-governance` -9. `test-workflow` - -The standalone markdown job still runs `task lint-md`, so CI and local `task -check` now cover the same authoritative surfaces. - -## Authoritative Lint Scope - -Sprint 07 tightened the lint scope to keep parity low-noise and reproducible: - -1. `lint-md` now targets authoritative root docs, docs content, custom agent - docs, skill docs, skill references, skill assets, and `.ub-workflows/`. -2. `lint-yaml` now targets authoritative root YAML files, workflow YAML, - skill `agents/openai.yaml` files, `high-risk-paths.yaml`, and the workflow - exception-template YAML. -3. Scratch `tmp/` content and repo-snapshot fixture trees are intentionally not - part of the lint baseline. - -## Fixture Coverage - -Static repository-integrity fixtures now live under: - -`./.agents/skills/ub-governance/tests/governance_scripts/fixtures/repo_integrity/` - -Covered cases: - -1. `pass/`: - authoritative pass-state repo snapshot with ignored `tmp/` noise -2. `fail-readme-agent-drift/`: - README inventory drift -3. `fail-package-metadata-drift/`: - version and marketplace count drift -4. `fail-legacy-root-registry/`: - legacy `AGENTS.MD` path-case mismatch -5. `fail-skill-schema/`: - missing frontmatter and broken local skill reference - -## Validation Proof - -Passed commands for Sprint 07: - -1. `uv run python -m unittest discover -s .agents/skills/ub-governance/tests/governance_scripts -p 'test_*.py' -v` -2. `task test-repo-catalog` -3. `task test-package-metadata` -4. `task test-repo-paths` -5. `task test-skill-schema` -6. `task test-governance-integrity` -7. `task test-governance` -8. `task test-workflow` -9. `task check` diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/07-ci-parity-and-regression-coverage/sprint.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/07-ci-parity-and-regression-coverage/sprint.md deleted file mode 100644 index 210d89e..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/07-ci-parity-and-regression-coverage/sprint.md +++ /dev/null @@ -1,132 +0,0 @@ -# Sprint PRD - -## Summary - -Make local and CI quality coverage match for the repository-integrity, -governance, and workflow checks that exist after Sprint 02. This sprint should -extend the existing Taskfile and GitHub Actions quality workflow so the new -integrity baseline, the existing governance regression suite, and the existing -workflow regression suite all run through one visible, reproducible path. - -## Scope - -1. Add Taskfile entrypoints for the new repository-integrity checkers and make - `task check` the closest local parity mirror of CI. -2. Extend `./.github/workflows/quality.yml` so the workflow regression suite - runs in CI alongside markdown, YAML, Ruff, and governance checks. -3. Add pass and fail fixtures that cover inventory drift, version drift, - stale references, path-case mismatches, broken skill references, and ignored - `./tmp/` scope behavior. -4. Keep the CI additions incremental by reusing the existing workflow matrix - and current direct-CLI test commands rather than inventing a separate CI - path. - -## Dependencies - -1. Sprint 06 must complete first so the new checker entrypoints and baseline - test expectations are stable enough to wire into local and CI parity. -2. Use `./prd.md` sections 14, 17, 18 action 6, and 20 as the product - contract for local/CI parity and deterministic regression coverage. -3. Build on the current Taskfile and GitHub Actions quality workflow instead of - replacing them wholesale. - -## Repository Truth At Sprint Start - -1. `./Taskfile.yml` already defines `test-integrity`, `test-governance`, - `test-workflow`, and `check`, but `test-integrity` currently points only to - `check_skill_integrity.py`. -2. `./.github/workflows/quality.yml` currently runs markdown, Ruff, YAML, - governance integrity, and governance regression checks, but it does not yet - run `test-workflow`. -3. `./.agents/skills/ub-workflow/tests/` already contains the workflow helper - regression suite that should be part of CI parity. -4. The repository already uses `uv`, `task`, and GitHub Actions matrices, so - this sprint should extend the current pattern rather than create a parallel - one. - -## Chosen Path - -Extend the existing Taskfile and GitHub Actions matrix in place, then add the -missing fixtures and regression cases around the new integrity scripts. This -keeps parity visible to contributors, preserves the current operator workflow, -and avoids a split where CI does things local developers never run. - -## Rejected Alternative - -Document the new checker commands but leave CI and local parity unchanged until -later. - -Pros: - -1. Minimizes immediate workflow-file churn. -2. Defers fixture-building effort. - -Cons: - -1. Leaves a known trust gap between local and CI behavior. -2. Makes regression coverage optional at the exact moment the baseline checker - surface is expanding. -3. Violates the PRD's explicit parity goal and delays detection of noisy or - unstable checks. - -## Affected Areas - -1. `./Taskfile.yml` -2. `./.github/workflows/quality.yml` -3. `./.agents/skills/ub-governance/tests/governance_scripts/` -4. `./.agents/skills/ub-workflow/tests/` -5. Any new governance or workflow fixture directories needed to exercise pass - and fail cases deterministically - -## Validation Plan - -1. Run `task check` locally and confirm it now covers the same integrity, - governance, workflow, and lint surfaces that CI runs. -2. Run `task test-workflow` directly to confirm the workflow regression suite - is green before and after CI wiring changes. -3. Re-run the governance and workflow unit-test discovery commands directly if - fixture failures need isolation. -4. Save fixture descriptions, expected pass/fail cases, and the final task or - matrix target list in `./evidence/` for later audit. -5. For the Level 1 `lean` governance bridge, record the final parity mapping - between Taskfile targets and CI jobs in the sprint closeout. - -## Exit Criteria - -1. Local `task check` is the closest parity mirror of CI for the integrity, - governance, workflow, and lint baseline. -2. CI runs the workflow regression suite and the new repository-integrity - checks introduced in Sprint 02. -3. Regression fixtures exist for the high-value drift cases named in the PRD, - and Sprint closeout records where they live and how they are invoked. - -## Final Audit Checklist - -Use this checklist only when this sprint is the final audit sprint. - -- [ ] roadmap scope was actually executed or explicitly deferred -- [ ] no material work was silently skipped -- [ ] initiative-level validation is recorded and traceable -- [ ] relevant documentation and synchronized artifacts reflect the shipped behavior -- [ ] follow-up audit or refactor decisions were captured -- [ ] `retained-note.md` is ready to record the final state - -## Handoff Expectation - -Sprint 08 should read this sprint's `closeout.md` first, then inspect the final -Taskfile and CI parity wiring. Its first task is to define the placeholder -token contract for generated initiative artifacts and add deterministic -placeholder-completeness reporting to `ub-workflow` without broadening the -scope to canonical templates. - -## Definition Of Done - -This sprint is done only when all of the following are true: - -1. planned functionality is complete or explicitly blocked -2. known in-scope issues are documented -3. required validation is run or explicitly deferred -4. relevant documentation and synchronized artifacts are updated or explicitly marked unchanged -5. validation evidence is recorded and traceable -6. governance bridge requirements are satisfied or explicitly marked not applicable -7. closeout is current and resumable diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/08-workflow-placeholder-hardening/closeout.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/08-workflow-placeholder-hardening/closeout.md deleted file mode 100644 index 7f3c544..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/08-workflow-placeholder-hardening/closeout.md +++ /dev/null @@ -1,176 +0,0 @@ -# Sprint Closeout - -## environment_note - -Executed in the local macOS workspace at -`/Users/itechnology/Dev/itech-agents`. Sprint 08 changed the ub-workflow -helper, added a direct placeholder-check CLI, expanded the workflow regression -suite, and updated the ub-workflow references to define the generated-output -placeholder contract explicitly. - -## scope_note - -This sprint defined the placeholder token contract for generated initiative -artifacts, added `check_scaffold_placeholders.py`, integrated deterministic -placeholder reporting and optional strict enforcement into -`scaffold_initiative.py`, and extended ub-workflow regression coverage for -required-versus-advisory behavior. It did not change repository packaging -policy or skill-surface uplift work; that remains Sprint 09. Governance bridge: -`Level 1`, profile `lean`. - -## decision_note - -Chosen path: classify generated-output placeholders explicitly, scan only the -generated initiative artifact surface by default, and separate required -blocking findings from advisory authoring prompts so strict mode can be useful -without treating canonical templates or prose examples as failures. - -Rejected alternative: treat any `Replace with...` or `REPLACE_` string anywhere -in the repository as an unconditional failure. - -Pros of the rejected alternative: - -1. Very small implementation surface. -2. Fast to explain. - -Cons of the rejected alternative: - -1. It confuses canonical templates and generated output. -2. It flags prose examples and code fences instead of only unresolved output. -3. It creates enough false positives to weaken trust in strict mode. - -## gate_note - -sprint_closeout: pass - -Sprint 08 completed the generated-output placeholder contract, the direct CLI -checker, the scaffold-helper integration, and the workflow regression coverage. -The live initiative now scans with `0 required` placeholder findings and only -advisory future-closeout prompts. - -confidence: pass - -When governance is active, also record the governance gate type and result as -`merge|confidence|release: pass|fail|blocked`. - -## exception_note - -none - -When governance is active, reference exception records that use the canonical -governance exception metadata. - -## validation_note - -Validation commands and outcomes: - -1. `uv run ruff check .agents/skills/ub-workflow/scripts .agents/skills/ub-workflow/tests/test_scaffold_initiative.py` - - Result: pass. - -2. `uv run python -m unittest discover -s .agents/skills/ub-workflow/tests -p 'test_*.py' -v` - - Result: pass with 20 workflow regression tests, including the new - placeholder visibility, strict-failure, strict-success, and false-positive - avoidance cases. - -3. `uv run python .agents/skills/ub-workflow/scripts/check_scaffold_placeholders.py ./.ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening --format json` - - Result: pass with `requiredCount: 0` and `advisoryCount: 32`; the live - initiative only retains advisory Sprint 08 handoff reminders plus future - closeout authoring prompts. - -4. Disposable initiative CLI proof: - - Result: confirmed create-time placeholder visibility, strict failure on - placeholder-only sprint shells after `init-sprints`, and strict success - after `prepare-sprints --strict-placeholders` when only advisory findings - remained. - -5. `task check` - - Result: pass after the ub-workflow placeholder checker, helper changes, and - references were added. - -Documentation and synchronized-artifact validation: - -1. `references/placeholder-contract.md` records the canonical required versus - advisory contract. -2. `references/scaffold-helper.md` documents the new checker and the - `--strict-placeholders` helper flags. -3. `references/scaffold-adaptation.md` now points to the explicit enforcement - rules for generated initiative output. -4. `SKILL.md` now tells operators when to load the placeholder contract. - -TG001-TG005 note: - -1. No separate TG001-TG005 product test run was required. This sprint changed - workflow helper behavior and workflow regressions, and the updated - ub-workflow test suite passed. - -Governance-level validation note: - -1. Profile: `lean` -2. Evidence path: `./evidence/placeholder-contract-and-cli-proof.md` -3. Advisory-only classes retained by design: `prd.md` authoring prompts, - generated `closeout.md` prompts, and `PENDING_HANDOFF:` markers - -Also record any documentation or synchronized-artifact validation that was required for this sprint. - -When tests changed, record whether TG001-TG005 checks were run and what they -reported. - -When governance is active, record governance-level validation commands, profile, -ADR references, and evidence paths that informed the gate decision. - -## done_verification_note - -Sprint 08 definition of done is satisfied. - -1. Planned functionality implemented: yes -2. Known in-scope errors still open: none -3. Required quality gates green: yes -4. Relevant docs and synchronized artifacts updated or explicitly unchanged: - updated -5. Validation evidence recorded: yes - -Minimum questions to answer: - -1. Is the planned functionality implemented? -2. Are there any known in-scope errors still open? -3. Are the required project quality gates green, including TG001-TG005 checks - when tests changed? -4. Are the relevant docs and synchronized artifacts updated or explicitly unchanged? -5. Is the validation evidence recorded? - -## handoff_note - -1. Finished: ub-workflow now has an explicit placeholder contract, a direct - generated-output checker, scaffold-helper summary reporting, strict - placeholder enforcement hooks, and regression coverage for both blocking and - advisory classes. -2. Open: repository packaging policy and targeted skill-surface uplift remain - for Sprint 09. -3. Next recommended action: start Sprint 09 - Packaging Policy And Targeted - Skill Uplift. -4. The next sprint should read this closeout first, then inspect - `references/placeholder-contract.md`, - `scripts/check_scaffold_placeholders.py`, - `scripts/scaffold_initiative.py`, and the updated ub-workflow tests. - -## follow_up_note - -No additional follow-up work was requested during Sprint 08 beyond the planned -Sprint 09 packaging and skill-uplift work. The placeholder contract now leaves -`prd.md`, generated `closeout.md`, and `PENDING_HANDOFF:` findings advisory by -design; later sprints can tighten those classes only if the workflow model -changes deliberately. - -For the final audit sprint, answer at minimum: - -1. Was the user asked whether they want follow-up audits or refactors? -2. Which follow-up items were requested, if any? -3. Which follow-up items were explicitly declined, if any? -4. Did the final validation and documentation synchronization checks pass? -5. Are any governance exceptions, ADR waivers, or follow-up validation items - still open? diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/08-workflow-placeholder-hardening/evidence/.gitkeep b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/08-workflow-placeholder-hardening/evidence/.gitkeep deleted file mode 100644 index 2fa992c..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/08-workflow-placeholder-hardening/evidence/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -keep diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/08-workflow-placeholder-hardening/evidence/placeholder-contract-and-cli-proof.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/08-workflow-placeholder-hardening/evidence/placeholder-contract-and-cli-proof.md deleted file mode 100644 index 6bb5a03..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/08-workflow-placeholder-hardening/evidence/placeholder-contract-and-cli-proof.md +++ /dev/null @@ -1,81 +0,0 @@ -# Sprint 08 Evidence - -## Placeholder Contract - -Sprint 08 defined the generated-output placeholder contract in -`./.agents/skills/ub-workflow/references/placeholder-contract.md`. - -Contract summary: - -1. Validation scope is generated initiative output, not canonical internal - templates. -2. `REPLACE_*` tokens are always required in generated initiative output. -3. Plain-language `Replace with ...` prompts are required in `roadmap.md` and - `sprints/*/sprint.md`. -4. Plain-language `Replace with ...` prompts are advisory in `prd.md` and - generated `closeout.md` files. -5. `PENDING_HANDOFF:` markers are advisory. -6. Fenced-code examples and quoted prose about placeholder strings are not - treated as unresolved generated-output placeholders. - -## Implemented Surfaces - -Sprint 08 added or updated these workflow surfaces: - -1. `./.agents/skills/ub-workflow/scripts/check_scaffold_placeholders.py` -2. `./.agents/skills/ub-workflow/scripts/scaffold_initiative.py` -3. `./.agents/skills/ub-workflow/tests/test_scaffold_initiative.py` -4. `./.agents/skills/ub-workflow/references/placeholder-contract.md` -5. `./.agents/skills/ub-workflow/references/scaffold-helper.md` -6. `./.agents/skills/ub-workflow/references/scaffold-adaptation.md` -7. `./.agents/skills/ub-workflow/SKILL.md` - -## Disposable CLI Proof - -Sprint 08 validated three direct CLI behaviors against disposable initiative -roots: - -1. `create` prints a generated-output placeholder summary immediately after - scaffolding. -2. `check_scaffold_placeholders.py --strict` fails for placeholder-only sprint - shells created by `init-sprints` before roadmap-derived sprint preparation. -3. `prepare-sprints --strict-placeholders` passes once the sprint PRDs are - rendered and only advisory findings remain. - -Observed proof points: - -1. Create-state scan reported required roadmap placeholders plus advisory PRD - prompts, making the incomplete generated output visible without blocking by - default. -2. Strict init-state scan exited non-zero with unresolved `REPLACE_SPRINT_*` - findings in the generated `sprint.md` shell. -3. Strict prepare-state scan completed successfully with `0 required` findings - and only advisory PRD prompts, generated closeout prompts, and - `PENDING_HANDOFF:` markers remaining. - -## Live Initiative Scan - -Direct command: - -1. `uv run python .agents/skills/ub-workflow/scripts/check_scaffold_placeholders.py ./.ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening --format json` - -Result: - -1. `status: pass` -2. `requiredCount: 0` -3. `advisoryCount: 32` - -The advisory findings are expected `PENDING_HANDOFF:` reminders in the Sprint 08 -closeout plus future-closeout authoring prompts in Sprint 09 through Sprint 11. -No blocking generated-output placeholder findings remain in the active -initiative state. - -## Regression Coverage - -Workflow regression coverage now proves: - -1. create-time placeholder visibility -2. strict failure on placeholder-only sprint shells -3. strict success after prepared sprint rendering when only advisory findings - remain -4. ignored code examples and quoted prose about placeholder strings diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/08-workflow-placeholder-hardening/sprint.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/08-workflow-placeholder-hardening/sprint.md deleted file mode 100644 index d119f5f..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/08-workflow-placeholder-hardening/sprint.md +++ /dev/null @@ -1,135 +0,0 @@ -# Sprint PRD - -## Summary - -Harden `ub-workflow` so generated initiative output makes unresolved -placeholders visible and can optionally fail in strict mode when required -placeholder tokens remain unresolved. This sprint turns the current manual -placeholder discipline into a deterministic generated-artifact check without -treating the canonical internal templates as if they were themselves -violations. - -## Scope - -1. Define the placeholder token contract for generated initiative artifacts so - the checker validates an explicit rule instead of ad hoc assumptions. -2. Add `check_scaffold_placeholders.py` under - `./.agents/skills/ub-workflow/scripts/`. -3. Integrate generated-output placeholder scanning into - `./.agents/skills/ub-workflow/scripts/scaffold_initiative.py` where it adds - deterministic visibility or strict-mode enforcement. -4. Extend workflow regression tests with required-versus-optional placeholder - cases and generated-artifact scope rules. - -## Dependencies - -1. Sprint 07 must complete first so workflow tests and CI parity are already - in place before placeholder-hardening logic expands the workflow surface. -2. Use `./prd.md` section 11.5, section 17 phase 3, section 18 action 5, and - the current generated sprint pack as the functional contract for this work. -3. Reuse the existing `scaffold_initiative.py` helper rather than creating a - second competing scaffold path. - -## Repository Truth At Sprint Start - -1. `./.agents/skills/ub-workflow/scripts/scaffold_initiative.py` currently - supports `create`, `init-sprints`, and `archive`, but no dedicated generated - placeholder completeness check. -2. `unresolved_placeholder_found()` currently uses a broad string test and is - only applied to selected control files rather than to generated initiative - output as a first-class product surface. -3. The current initiative under - `./.ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening/` - began with placeholder-only sprint PRDs, which is the concrete failure mode - this sprint must make visible or prevent. -4. Placeholder validation must apply to generated initiative artifacts, not to - canonical internal templates by default. - -## Chosen Path - -Add an explicit generated-output placeholder checker and integrate it -conservatively with the scaffold helper. The checker should classify required -versus optional unresolved placeholders, print deterministic summaries, and -support strict-mode failure for required tokens while leaving canonical -template files outside the default validation scope. - -## Rejected Alternative - -Treat any `Replace with...` or `REPLACE_` string anywhere in the repository as -an unconditional failure. - -Pros: - -1. Easy to implement. -2. Would catch unresolved generated placeholders quickly. - -Cons: - -1. Confuses canonical templates with generated initiative outputs. -2. Creates noisy failures that weaken trust in the checker. -3. Breaks the PRD's explicit scope rule for placeholder validation. - -## Affected Areas - -1. `./.agents/skills/ub-workflow/scripts/scaffold_initiative.py` -2. `./.agents/skills/ub-workflow/scripts/check_scaffold_placeholders.py` -3. `./.agents/skills/ub-workflow/tests/` -4. `./.agents/skills/ub-workflow/references/scaffold-helper.md` -5. `./.agents/skills/ub-workflow/references/scaffold-adaptation.md` -6. Generated initiative outputs under `./.ub-workflows/initiatives/` as test - fixtures or smoke-test targets - -## Validation Plan - -1. Run the new placeholder checker directly with `uv run python` against - generated initiative fixtures that include both required and optional - unresolved placeholders. -2. Re-run `uv run python -m unittest discover -s .agents/skills/ub-workflow/tests - -p 'test_*.py' -v` after adding generated-output placeholder cases. -3. Verify that canonical template files do not trigger default failures and - record that scope decision in `./evidence/`. -4. Record one deterministic summary example and one strict-mode failure example - under `./evidence/` so later audits can confirm the behavior remained - explicit. -5. For the Level 1 `lean` governance bridge, record whether any placeholder - classes remain advisory rather than blocking and why. - -## Exit Criteria - -1. `ub-workflow` has deterministic generated-output placeholder reporting and - optional strict-mode failure for required unresolved placeholders. -2. Workflow regression tests cover required-versus-optional placeholder cases - and generated-output scope discipline. -3. Sprint closeout records the placeholder contract and the exact files or - commands Sprint 05 should treat as the new workflow baseline. - -## Final Audit Checklist - -Use this checklist only when this sprint is the final audit sprint. - -- [ ] roadmap scope was actually executed or explicitly deferred -- [ ] no material work was silently skipped -- [ ] initiative-level validation is recorded and traceable -- [ ] relevant documentation and synchronized artifacts reflect the shipped behavior -- [ ] follow-up audit or refactor decisions were captured -- [ ] `retained-note.md` is ready to record the final state - -## Handoff Expectation - -Sprint 09 should read this sprint's `closeout.md` first, then inspect the final -placeholder contract and updated workflow references. Its first task is to -document the repository packaging policy, decide the status of -`agents/openai.yaml`, and make targeted quality improvements to the most -inconsistent skill surfaces without broad churn. - -## Definition Of Done - -This sprint is done only when all of the following are true: - -1. planned functionality is complete or explicitly blocked -2. known in-scope issues are documented -3. required validation is run or explicitly deferred -4. relevant documentation and synchronized artifacts are updated or explicitly marked unchanged -5. validation evidence is recorded and traceable -6. governance bridge requirements are satisfied or explicitly marked not applicable -7. closeout is current and resumable diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/09-packaging-policy-and-skill-uplift/closeout.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/09-packaging-policy-and-skill-uplift/closeout.md deleted file mode 100644 index c13fdfb..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/09-packaging-policy-and-skill-uplift/closeout.md +++ /dev/null @@ -1,150 +0,0 @@ -# Sprint Closeout - -## environment_note - -Executed in the local macOS workspace at -`/Users/itechnology/Dev/itech-agents`. Sprint 09 changed documentation and -skill surfaces only: it added the packaging policy document under `./docs/`, -updated `ub-python`, and made two narrow skill-structure consistency fixes. -No governance scripts or workflow helper code changed in this sprint. - -## scope_note - -This sprint defined the repository packaging contract, made the -`agents/openai.yaml` stance explicit, deepened `ub-python` with repository-truth -validation guidance, and normalized only the highest-value documentation -structure gaps in `ub-css` and `ub-customizations`. It did not perform a -repo-wide skill rewrite or add new integrity gates beyond the documented -policy. Governance bridge: `Level 1`, profile `lean`. - -## decision_note - -Chosen path: document one minimal packaging policy grounded in the existing -integrity baseline, then apply only a small number of policy-driven skill -uplifts where contributor guidance was materially weaker or structurally less -explicit. - -Rejected alternative: do a repo-wide skill-surface normalization pass while -also writing the packaging policy. - -Pros of the rejected alternative: - -1. More visible consistency in one sweep. -2. More opportunities to catch low-level drift quickly. - -Cons of the rejected alternative: - -1. It would mix policy decisions with broad cosmetic churn. -2. It would make the `openai.yaml` decision harder to evaluate cleanly. -3. It would expand the sprint well beyond the PRD's narrow implementation slice. - -## gate_note - -sprint_closeout: pass - -Sprint 09 completed the minimal packaging-policy contract, settled -`agents/openai.yaml` as optional, improved `ub-python` against the repository's -real Python baseline, and kept the repository validation baseline green. - -confidence: pass - -When governance is active, also record the governance gate type and result as -`merge|confidence|release: pass|fail|blocked`. - -## exception_note - -none - -When governance is active, reference exception records that use the canonical -governance exception metadata. - -## validation_note - -Validation commands and outcomes: - -1. `npx --yes markdownlint-cli2 docs/packaging-policy.md .agents/skills/ub-python/SKILL.md .agents/skills/ub-python/references/repository-python-workflows.md .agents/skills/ub-css/SKILL.md .agents/skills/ub-customizations/SKILL.md` - - Result: pass. - -2. `uv run python .agents/skills/ub-governance/scripts/check_skill_schema.py` - - Result: pass. - -3. `task check` - - Result: pass. - -Documentation and synchronized-artifact validation: - -1. `docs/packaging-policy.md` now records the canonical package contract. -2. `ub-python` now documents the repository's real Python validation baseline. -3. `ub-css` and `ub-customizations` now expose the missing output or completion - guidance surfaces that were the highest-value structural inconsistencies. - -TG001-TG005 note: - -1. No separate TG001-TG005 product test run was required. This sprint changed - repository documentation and skill guidance, and the repo-wide baseline - stayed green. - -Governance-level validation note: - -1. Profile: `lean` -2. Evidence path: `./evidence/packaging-policy-and-targeted-uplift.md` -3. Policy restraint: `agents/openai.yaml` remains optional rather than being - promoted to a new enforced packaging gate - -Also record any documentation or synchronized-artifact validation that was required for this sprint. - -When tests changed, record whether TG001-TG005 checks were run and what they -reported. - -When governance is active, record governance-level validation commands, profile, -ADR references, and evidence paths that informed the gate decision. - -## done_verification_note - -Sprint 09 definition of done is satisfied. - -1. Planned functionality implemented: yes -2. Known in-scope errors still open: none -3. Required quality gates green: yes -4. Relevant docs and synchronized artifacts updated or explicitly unchanged: - updated -5. Validation evidence recorded: yes - -Minimum questions to answer: - -1. Is the planned functionality implemented? -2. Are there any known in-scope errors still open? -3. Are the required project quality gates green, including TG001-TG005 checks - when tests changed? -4. Are the relevant docs and synchronized artifacts updated or explicitly unchanged? -5. Is the validation evidence recorded? - -## handoff_note - -1. Finished: the packaging policy is now explicit, `agents/openai.yaml` is - explicitly optional, `ub-python` reflects repository Python truth, and the - selected structural guidance gaps are closed. -2. Open: freshness and portability review remain for Sprint 10. -3. Next recommended action: start Sprint 10 - Freshness And Portability Review. -4. The next sprint should read this closeout first, then inspect - `./docs/packaging-policy.md`, `ub-python`, and the evidence document for the - final `openai.yaml` decision and policy-restraint rationale. - -## follow_up_note - -No additional follow-up work was requested during Sprint 09 beyond the planned -Sprint 10 freshness and portability review. The packaging contract intentionally -stops short of requiring optional skill assets until the repository has a real -operational reason to enforce them. - -For the final audit sprint, answer at minimum: - -1. Was the user asked whether they want follow-up audits or refactors? -2. Which follow-up items were requested, if any? -3. Which follow-up items were explicitly declined, if any? -4. Did the final validation and documentation synchronization checks pass? -5. Are any governance exceptions, ADR waivers, or follow-up validation items - still open? diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/09-packaging-policy-and-skill-uplift/evidence/.gitkeep b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/09-packaging-policy-and-skill-uplift/evidence/.gitkeep deleted file mode 100644 index 2fa992c..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/09-packaging-policy-and-skill-uplift/evidence/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -keep diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/09-packaging-policy-and-skill-uplift/evidence/packaging-policy-and-targeted-uplift.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/09-packaging-policy-and-skill-uplift/evidence/packaging-policy-and-targeted-uplift.md deleted file mode 100644 index 98a6a43..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/09-packaging-policy-and-skill-uplift/evidence/packaging-policy-and-targeted-uplift.md +++ /dev/null @@ -1,63 +0,0 @@ -# Sprint 09 Evidence - -## Packaging Policy Decision - -Sprint 09 added the canonical packaging policy document at -`./docs/packaging-policy.md`. - -Key contract decisions: - -1. a skill package only requires `SKILL.md` -2. `references/`, `assets/`, `agents/`, `docs/`, `scripts/`, and `tests/` are - optional support surfaces -3. custom-agent registry truth remains the `.github/agents/*.agent.md` files -4. plugin metadata synchronization remains anchored to `pyproject.toml`, - `plugin.json`, and `.github/plugin/marketplace.json` - -## `agents/openai.yaml` Decision - -Status: optional - -Reasoning: - -1. the repository currently mixes skills with and without `agents/openai.yaml` -2. the active integrity baseline does not require it for package validity -3. making it required would add ceremony without improving the core inventory - or governance contract - -Operational outcome: - -1. keep `agents/openai.yaml` when a skill needs provider-specific interface - metadata -2. do not add it merely for symmetry -3. do not treat its absence as package drift - -## `ub-python` Uplift - -Sprint 09 deepened `ub-python` in two targeted ways: - -1. `SKILL.md` now loads a repository-specific Python workflow reference -2. `references/repository-python-workflows.md` records the real repository - Python baseline: `uv`, `ruff`, stdlib `unittest`, direct script execution, - and the absence of repository-wired mypy/pytest gates - -This closes the mismatch where `ub-python` previously described a more generic -Python toolchain than this repository actually enforces. - -## Structural Consistency Fixes - -Sprint 09 normalized only two high-value documentation inconsistencies: - -1. `ub-css` now includes an explicit `Output Requirements` section -2. `ub-customizations` now includes an explicit `Completion Checklist` - -The sprint intentionally avoided repo-wide skill normalization beyond those -high-value gaps. - -## Validation Proof - -Passed commands: - -1. `npx --yes markdownlint-cli2 docs/packaging-policy.md .agents/skills/ub-python/SKILL.md .agents/skills/ub-python/references/repository-python-workflows.md .agents/skills/ub-css/SKILL.md .agents/skills/ub-customizations/SKILL.md` -2. `uv run python .agents/skills/ub-governance/scripts/check_skill_schema.py` -3. `task check` diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/09-packaging-policy-and-skill-uplift/sprint.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/09-packaging-policy-and-skill-uplift/sprint.md deleted file mode 100644 index 4a1db40..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/09-packaging-policy-and-skill-uplift/sprint.md +++ /dev/null @@ -1,129 +0,0 @@ -# Sprint PRD - -## Summary - -Document the repository's packaging contract and apply only the highest-value -skill-surface improvements that the new integrity baseline makes necessary. -This sprint should make it clear what assets are required versus optional for a -skill or agent package, settle the stance on `agents/openai.yaml`, and deepen -the weakest or least consistent skill surfaces without turning the initiative -into a repo-wide rewrite. - -## Scope - -1. Create the canonical packaging-policy document that defines required versus - optional skill assets and makes the packaging contract actionable for - contributors. -2. Decide whether `agents/openai.yaml` is required, optional, or deprecated and - make that decision explicit rather than leaving it implied. -3. Deepen `./.agents/skills/ub-python/` so its references and guidance better - match the repository's actual Python usage and quality expectations. -4. Normalize only the highest-value structural inconsistencies, such as missing - output-contract sections, when they materially improve contributor guidance. - -## Dependencies - -1. Sprint 08 must complete first so the workflow surface is stable before - broader packaging policy and skill-surface documentation changes begin. -2. Use `./prd.md` sections 11.6, 13, 17 phase 4, 18 action 7, and 20 as the - product contract for packaging-policy scope and restraint. -3. Use the outputs of the new integrity baseline to decide what must become - policy instead of inventing requirements that the repository does not really - need. - -## Repository Truth At Sprint Start - -1. The repository currently has a mix of prose-first and operationally hardened - skills, but no canonical document that defines what packaging completeness - means. -2. `./.agents/skills/ub-python/` is a likely candidate for targeted reference - and structural improvement once the baseline integrity layer is in place. -3. The status of `agents/openai.yaml` is still under-specified and therefore - hard for contributors or tooling to interpret consistently. -4. This sprint should stay deliberately narrow: it is not a full normalization - pass across every skill. - -## Chosen Path - -Write one minimal policy document that answers the real packaging questions, -then apply targeted improvements only where the new policy or integrity checks -make a gap obvious. This keeps the sprint decision-oriented and avoids turning -policy clarification into broad stylistic cleanup. - -## Rejected Alternative - -Attempt a repo-wide skill-surface normalization pass at the same time as the -packaging policy. - -Pros: - -1. Could increase superficial consistency quickly. -2. Might surface hidden drift in one large pass. - -Cons: - -1. Expands scope far beyond the PRD's recommended first implementation slice. -2. Makes it harder to tell which changes are policy-driven versus cosmetic. -3. Risks delaying real policy clarity behind large prose edits. - -## Affected Areas - -1. `./docs/skill-schema.md` or the chosen packaging-policy document path -2. `./.agents/skills/ub-python/` -3. Any small number of other skill files whose structural inconsistencies are - explicitly selected for correction in this sprint -4. Potentially `./README.md` or `./AGENTS.md` only if the packaging policy must - be surfaced publicly after it is written - -## Validation Plan - -1. Run `npx --yes markdownlint-cli2` against the new packaging-policy document - and any touched skill documentation. -2. Re-run the relevant integrity checks introduced in Sprint 02 if packaging or - skill-structure changes affect their expected outputs. -3. Record the chosen `agents/openai.yaml` policy decision and the reasons for - it in `./evidence/` so Sprint 10 and Sprint 11 can treat it as a - settled contract. -4. If `ub-python` changes touch Python support files or examples, run the most - relevant lint or structural checks and record the exact command outcomes in - the sprint closeout. -5. For the Level 1 `lean` governance bridge, record why the chosen policy is - minimal enough to avoid bureaucracy while still being explicit. - -## Exit Criteria - -1. A canonical packaging-policy document exists and answers the minimum policy - questions named in the PRD. -2. The `agents/openai.yaml` stance is explicit and no longer implied. -3. The selected high-value skill-surface improvements are complete, validated, - and recorded for Sprint 06 and the final audit. - -## Final Audit Checklist - -Use this checklist only when this sprint is the final audit sprint. - -- [ ] roadmap scope was actually executed or explicitly deferred -- [ ] no material work was silently skipped -- [ ] initiative-level validation is recorded and traceable -- [ ] relevant documentation and synchronized artifacts reflect the shipped behavior -- [ ] follow-up audit or refactor decisions were captured -- [ ] `retained-note.md` is ready to record the final state - -## Handoff Expectation - -Sprint 10 should read this sprint's `closeout.md` first, then the final -packaging-policy document. Its first task is to add warning-only freshness -discipline for volatile skill guidance and clarify which core quality rules are -repository policy versus strong defaults for downstream portability. - -## Definition Of Done - -This sprint is done only when all of the following are true: - -1. planned functionality is complete or explicitly blocked -2. known in-scope issues are documented -3. required validation is run or explicitly deferred -4. relevant documentation and synchronized artifacts are updated or explicitly marked unchanged -5. validation evidence is recorded and traceable -6. governance bridge requirements are satisfied or explicitly marked not applicable -7. closeout is current and resumable diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/10-freshness-and-portability-review/closeout.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/10-freshness-and-portability-review/closeout.md deleted file mode 100644 index 2c607ca..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/10-freshness-and-portability-review/closeout.md +++ /dev/null @@ -1,152 +0,0 @@ -# Sprint Closeout - -## environment_note - -Executed in the local macOS workspace at -`/Users/itechnology/Dev/itech-agents`. Sprint 10 was documentation-only: it -added warning-only freshness guidance, clarified portability boundaries in the -core quality surface, and updated high-volatility skill docs without changing -the repository's blocking validation or CI behavior. - -## scope_note - -This sprint defined the advisory freshness discipline, added lightweight -freshness-review markers to the selected high-volatility skills, and clarified -policy-versus-default language in `AGENTS.md` and `ub-quality`. It did not add -any new checker, task, CI job, or machine-read metadata system. Governance -bridge: `Level 1`, profile `lean`. - -## decision_note - -Chosen path: use a lightweight documentation-based freshness layer and make -portability boundaries explicit in the repository's strongest quality surface. -This keeps volatile guidance reviewable without turning phase-1 hardening into -process theater. - -Rejected alternative: make freshness a blocking requirement across volatile -skills immediately. - -Pros of the rejected alternative: - -1. It would surface stale guidance aggressively. -2. It would force review behavior quickly. - -Cons of the rejected alternative: - -1. It conflicts with the PRD's warning-first direction. -2. It would add blocker noise before the advisory layer proves its value. -3. It would convert review priority signals into bureaucracy. - -## gate_note - -sprint_closeout: pass - -Sprint 10 completed the advisory freshness contract, clarified policy versus -strong defaults in the core quality surface, and kept the repository baseline -green without adding new blockers. - -confidence: pass - -When governance is active, also record the governance gate type and result as -`merge|confidence|release: pass|fail|blocked`. - -## exception_note - -none - -When governance is active, reference exception records that use the canonical -governance exception metadata. - -## validation_note - -Validation commands and outcomes: - -1. `npx --yes markdownlint-cli2 docs/freshness-policy.md AGENTS.md .agents/skills/ub-quality/SKILL.md .agents/skills/ub-quality/references/freshness-portability.md .agents/skills/ub-tailwind/SKILL.md .agents/skills/ub-nuxt/SKILL.md .agents/skills/ub-vuejs/SKILL.md .agents/skills/ub-ts/SKILL.md .agents/skills/ub-python/SKILL.md .agents/skills/ub-customizations/SKILL.md` - - Result: pass. - -2. `uv run python .agents/skills/ub-governance/scripts/check_skill_schema.py` - - Result: pass. - -3. `task check` - - Result: pass. - -Documentation and synchronized-artifact validation: - -1. `docs/freshness-policy.md` now records the canonical warning-only freshness - contract. -2. `AGENTS.md` now distinguishes repository policy from strong defaults. -3. `ub-quality` now documents the portability boundary through a dedicated - reference. -4. The selected high-volatility skills now surface advisory freshness markers. - -TG001-TG005 note: - -1. No separate TG001-TG005 product test run was required. This sprint changed - repository documentation and skill guidance only, and the repo-wide - validation baseline stayed green. - -Governance-level validation note: - -1. Profile: `lean` -2. Evidence path: `./evidence/advisory-freshness-and-portability.md` -3. Anti-bureaucracy outcome: no new blocking gate, CI job, or metadata parser - was introduced - -Also record any documentation or synchronized-artifact validation that was required for this sprint. - -When tests changed, record whether TG001-TG005 checks were run and what they -reported. - -When governance is active, record governance-level validation commands, profile, -ADR references, and evidence paths that informed the gate decision. - -## done_verification_note - -Sprint 10 definition of done is satisfied. - -1. Planned functionality implemented: yes -2. Known in-scope errors still open: none -3. Required quality gates green: yes -4. Relevant docs and synchronized artifacts updated or explicitly unchanged: - updated -5. Validation evidence recorded: yes - -Minimum questions to answer: - -1. Is the planned functionality implemented? -2. Are there any known in-scope errors still open? -3. Are the required project quality gates green, including TG001-TG005 checks - when tests changed? -4. Are the relevant docs and synchronized artifacts updated or explicitly unchanged? -5. Is the validation evidence recorded? - -## handoff_note - -1. Finished: the repository now has an explicit warning-only freshness policy, - volatile-skill review markers, and an explicit policy-versus-default - boundary in the core quality surfaces. -2. Open: the final audit still needs to verify every prior sprint landed, - confirm synchronized artifacts, and ask explicitly about follow-up audits or - refactors. -3. Next recommended action: start Sprint 11 - Final Audit. -4. The next sprint should read this closeout first, then inspect - `./docs/freshness-policy.md`, `AGENTS.md`, and the new `ub-quality` - freshness-portability reference. - -## follow_up_note - -No additional follow-up work was requested during Sprint 10 beyond the planned -final audit. The advisory freshness layer should remain non-blocking unless the -repository explicitly chooses stronger enforcement after later audit review. - -For the final audit sprint, answer at minimum: - -1. Was the user asked whether they want follow-up audits or refactors? -2. Which follow-up items were requested, if any? -3. Which follow-up items were explicitly declined, if any? -4. Did the final validation and documentation synchronization checks pass? -5. Are any governance exceptions, ADR waivers, or follow-up validation items - still open? diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/10-freshness-and-portability-review/evidence/.gitkeep b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/10-freshness-and-portability-review/evidence/.gitkeep deleted file mode 100644 index 2fa992c..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/10-freshness-and-portability-review/evidence/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -keep diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/10-freshness-and-portability-review/evidence/advisory-freshness-and-portability.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/10-freshness-and-portability-review/evidence/advisory-freshness-and-portability.md deleted file mode 100644 index d6a36ef..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/10-freshness-and-portability-review/evidence/advisory-freshness-and-portability.md +++ /dev/null @@ -1,63 +0,0 @@ -# Sprint 10 Evidence - -## Advisory Freshness Design - -Sprint 10 added the canonical advisory freshness policy document at -`./docs/freshness-policy.md`. - -Key decisions: - -1. freshness remains warning-only by default -2. high-volatility skills use lightweight documentation markers rather than a - new metadata registry -3. freshness markers are review signals, not blocking integrity or CI gates -4. the advisory layer must not weaken the existing packaging or integrity - baseline - -## High-Volatility Skill Markers - -Sprint 10 added `Freshness Review` sections to these skills: - -1. `ub-tailwind` -2. `ub-nuxt` -3. `ub-vuejs` -4. `ub-ts` -5. `ub-python` -6. `ub-customizations` - -Each marker records: - -1. volatility level -2. review recommendation -3. trigger signals -4. advisory-only enforcement status -5. stable core guidance that should survive recipe churn - -## Policy Versus Defaults Clarification - -Sprint 10 clarified portability boundaries in the core quality surfaces: - -1. `AGENTS.md` now distinguishes repository policy from strong defaults -2. `ub-quality` now points to a dedicated freshness-and-portability reference -3. `ub-quality` explicitly states that alignment and required-reference loading - are repository policy in this repo, while many sibling-skill setup patterns - remain strong defaults rather than universal rules - -## No New Blocking Layer - -Sprint 10 intentionally did not add: - -1. a freshness checker -2. a CI freshness job -3. a new task in `Taskfile.yml` -4. a metadata file that the integrity baseline must parse - -That restraint is part of the shipped behavior, not missing work. - -## Validation Proof - -Passed commands: - -1. `npx --yes markdownlint-cli2 docs/freshness-policy.md AGENTS.md .agents/skills/ub-quality/SKILL.md .agents/skills/ub-quality/references/freshness-portability.md .agents/skills/ub-tailwind/SKILL.md .agents/skills/ub-nuxt/SKILL.md .agents/skills/ub-vuejs/SKILL.md .agents/skills/ub-ts/SKILL.md .agents/skills/ub-python/SKILL.md .agents/skills/ub-customizations/SKILL.md` -2. `uv run python .agents/skills/ub-governance/scripts/check_skill_schema.py` -3. `task check` diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/10-freshness-and-portability-review/sprint.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/10-freshness-and-portability-review/sprint.md deleted file mode 100644 index 2910024..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/10-freshness-and-portability-review/sprint.md +++ /dev/null @@ -1,131 +0,0 @@ -# Sprint PRD - -## Summary - -Add advisory freshness discipline for volatile guidance and clarify the -portability boundaries of the repository's strongest quality surfaces. This -sprint should help maintainers prioritize review of fast-moving framework -guidance without turning freshness into blocking theater, and it should make -clear which core-quality rules are repository policy versus strong house -defaults that downstream users may need to adapt deliberately. - -## Scope - -1. Propose freshness metadata or review-cycle markers for high-volatility - skills such as Tailwind, Nuxt, Vue, TypeScript, Python tooling, and Copilot - customization guidance. -2. Keep the freshness layer warning-only by default and document why it is not - a blocking phase-1 control. -3. Clarify policy-versus-default language in the core quality surfaces where - portability friction is most likely. -4. Confirm that the advisory layer does not weaken the baseline integrity suite - or introduce new bureaucratic checks. - -## Dependencies - -1. Sprint 09 must complete first so packaging-policy decisions and targeted - skill uplift are already settled. -2. Use `./prd.md` sections 11.7, 11.8, 15 risks 3 and 7, 17 phase 4, and 18 - action 8 as the product contract for this work. -3. Reuse the baseline integrity and packaging-policy outputs from prior sprints - rather than inventing a parallel metadata system. - -## Repository Truth At Sprint Start - -1. The repository contains several high-volatility guidance areas, especially - around Tailwind, Nuxt, Vue, TypeScript, Python tooling, and Copilot - customization behavior. -2. The PRD explicitly warns that freshness should be advisory first and that - stable principles must be distinguished from volatile setup recipes. -3. The repository's core quality surfaces are strong, but the PRD notes that - portability concerns need clearer wording so downstream users can separate - hard policy from strong defaults. -4. No freshness-review metadata or portability-boundary clarification currently - exists as a durable, explicit contract. - -## Chosen Path - -Add a lightweight warning-only freshness design and make portability boundaries -explicit in the most relevant quality surfaces. This preserves the repository's -strong opinions while preventing the phase-1 hardening effort from expanding -into an overbearing review bureaucracy. - -## Rejected Alternative - -Make freshness a blocking requirement across volatile skills immediately. - -Pros: - -1. Forces review discipline quickly. -2. Makes stale high-volatility guidance more visible. - -Cons: - -1. Conflicts with the PRD's warning-first recommendation. -2. Risks producing noisy blockers before the baseline integrity layer proves - stable and trusted. -3. Turns advisory review into ceremony instead of maintainable prioritization. - -## Affected Areas - -1. Volatile skill surfaces under `./.agents/skills/` such as `ub-tailwind/`, - `ub-nuxt/`, `ub-vuejs/`, `ub-ts/`, `ub-python/`, and - `ub-customizations/` -2. `./.agents/skills/ub-quality/` or adjacent core-quality references where - portability-boundary wording needs clarification -3. Any packaging-policy or reference doc updated to host freshness-review - guidance or policy/default distinctions - -## Validation Plan - -1. Run `npx --yes markdownlint-cli2` on every touched documentation or skill - surface. -2. Re-run the baseline integrity suite after changes to confirm the advisory - layer did not create new blocking failures or invalidate the packaging - contract. -3. Record the final freshness policy, review-cycle recommendation, and any - clarified policy-versus-default wording in `./evidence/`. -4. Confirm in the sprint closeout that the freshness layer remains advisory and - that no CI blocker was introduced by this sprint. -5. For the Level 1 `lean` governance bridge, explicitly note why the chosen - approach avoids turning the repository into process theater. - -## Exit Criteria - -1. A warning-only freshness discipline exists for the chosen high-volatility - surfaces. -2. Policy-versus-default wording is clearer in the core quality surfaces where - portability concerns matter most. -3. Sprint closeout confirms that the advisory layer did not weaken the baseline - integrity posture or create new blocking noise. - -## Final Audit Checklist - -Use this checklist only when this sprint is the final audit sprint. - -- [ ] roadmap scope was actually executed or explicitly deferred -- [ ] no material work was silently skipped -- [ ] initiative-level validation is recorded and traceable -- [ ] relevant documentation and synchronized artifacts reflect the shipped behavior -- [ ] follow-up audit or refactor decisions were captured -- [ ] `retained-note.md` is ready to record the final state - -## Handoff Expectation - -Sprint 11 should read this sprint's `closeout.md` first, then the -updated policy and freshness artifacts. Its first task is to verify that every -prior sprint actually landed, that synchronized docs and validation outputs are -current, and that the user is asked explicitly about follow-up audits or -refactors before any archive step is considered. - -## Definition Of Done - -This sprint is done only when all of the following are true: - -1. planned functionality is complete or explicitly blocked -2. known in-scope issues are documented -3. required validation is run or explicitly deferred -4. relevant documentation and synchronized artifacts are updated or explicitly marked unchanged -5. validation evidence is recorded and traceable -6. governance bridge requirements are satisfied or explicitly marked not applicable -7. closeout is current and resumable diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/11-final-audit/closeout.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/11-final-audit/closeout.md deleted file mode 100644 index 091cb1b..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/11-final-audit/closeout.md +++ /dev/null @@ -1,162 +0,0 @@ -# Sprint Closeout - -## environment_note - -Executed in the local macOS workspace at -`/Users/itechnology/Dev/itech-agents`. Sprint 11 performed an evidence-driven -final audit over the repository state, prior sprint closeouts, prior sprint -evidence, and the final control surfaces `README.md`, `roadmap.md`, and -`retained-note.md`. - -## scope_note - -This sprint verified that Sprint 01 through Sprint 10 actually landed, that -the canonical repository docs and validation outputs are synchronized with the -shipped behavior, that follow-up decisions are explicit, and that the -initiative is ready for human archive review. It did not archive the initiative -because archive remains an explicit post-audit human decision. Governance -bridge: `Level 1`, profile `lean`. - -## decision_note - -Chosen path: audit the initiative from evidence outward by rechecking prior -closeouts, sprint evidence, the live repository state, and the final control -surfaces before writing the retained note and archive-ready status. - -Rejected alternative: treat a green `task check` run as sufficient proof of -initiative completion and skip the retained-note plus closeout audit. - -Pros of the rejected alternative: - -1. It is the fastest path to closure. -2. It minimizes audit-writing overhead. - -Cons of the rejected alternative: - -1. It does not prove every roadmap sprint actually landed. -2. It can miss missing retained-note, follow-up, or archive-readiness state. -3. It conflicts with the workflow contract's explicit human review pause before archive. - -## gate_note - -archive_ready: pass - -The final audit is complete. Sprint 01 through Sprint 10 all have passing -closeouts and substantive evidence, the final validation baseline is green, -follow-up decisions are explicit, and `retained-note.md` is written. Archive -remains pending explicit human approval. - -confidence: pass - -When governance is active, also record the governance gate type and result as -`merge|confidence|release: pass|fail|blocked`. - -## exception_note - -none - -When governance is active, reference exception records that use the canonical -governance exception metadata. - -## validation_note - -Validation commands and outcomes: - -1. Prior sprint audit across Sprint 01 through Sprint 10 closeouts and evidence - - Result: pass; every prior sprint has a closeout, every prior closeout marks - `sprint_closeout: pass`, no active blocker or exception remains, and each - sprint evidence folder contains substantive markdown evidence. - -2. `task check` - - Result: pass. - -3. `uv run python .agents/skills/ub-workflow/scripts/check_scaffold_placeholders.py ./.ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening --strict` - - Result: pass. - -4. `uv run python .agents/skills/ub-workflow/scripts/scaffold_initiative.py archive ./.ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening --dry-run` - - Result: pass; the initiative is archive-ready, but archive was not executed. - -Documentation and synchronized-artifact validation: - -1. `README.md`, `roadmap.md`, and `retained-note.md` now tell the same final - completion story. -2. Packaging, freshness, and placeholder policy documents remain aligned with - the implemented scripts and validation baseline. -3. The roadmap now records all sprint closeouts complete, the final audit done, - the follow-up decision recorded, and the retained note written. - -TG001-TG005 note: - -1. No separate TG001-TG005 product test run was required. The final audit - revalidated the repository-wide baseline rather than changing product logic. - -Governance-level validation note: - -1. Profile: `lean` -2. Evidence path: `./evidence/final-audit-summary.md` -3. Follow-up decision: no additional audits or refactors were requested - -Also record any documentation or synchronized-artifact validation that was required for this sprint. - -When tests changed, record whether TG001-TG005 checks were run and what they -reported. - -When governance is active, record governance-level validation commands, profile, -ADR references, and evidence paths that informed the gate decision. - -## done_verification_note - -Sprint 11 definition of done is satisfied. - -1. Planned functionality implemented: yes -2. Known in-scope errors still open: none -3. Required quality gates green: yes -4. Relevant docs and synchronized artifacts updated or explicitly unchanged: - updated -5. Validation evidence recorded: yes - -Minimum questions to answer: - -1. Is the planned functionality implemented? -2. Are there any known in-scope errors still open? -3. Are the required project quality gates green, including TG001-TG005 checks - when tests changed? -4. Are the relevant docs and synchronized artifacts updated or explicitly unchanged? -5. Is the validation evidence recorded? - -## handoff_note - -1. Finished: the initiative has a complete final audit, a written retained note, - explicit follow-up decisions, and archive-ready status. -2. Open: archive has not been executed and still requires explicit human approval. -3. Next recommended action: review `retained-note.md`, `README.md`, and this - closeout, then decide whether to archive the initiative. -4. There is no next implementation sprint. Any next operator should read this - closeout first, then `./retained-note.md`, then `./README.md` before any - archive action. - -## follow_up_note - -The user explicitly declined additional follow-up audits and refactors during -the final audit. - -1. Follow-up audits requested: none -2. Follow-up refactors requested: none -3. Follow-up items explicitly declined: additional audits and refactors beyond - this initiative -4. Final validation and documentation synchronization checks passed: yes -5. Remaining governance exceptions, ADR waivers, or follow-up validation items: - none - -For the final audit sprint, answer at minimum: - -1. Was the user asked whether they want follow-up audits or refactors? -2. Which follow-up items were requested, if any? -3. Which follow-up items were explicitly declined, if any? -4. Did the final validation and documentation synchronization checks pass? -5. Are any governance exceptions, ADR waivers, or follow-up validation items - still open? diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/11-final-audit/evidence/.gitkeep b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/11-final-audit/evidence/.gitkeep deleted file mode 100644 index 2fa992c..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/11-final-audit/evidence/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -keep diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/11-final-audit/evidence/final-audit-summary.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/11-final-audit/evidence/final-audit-summary.md deleted file mode 100644 index f3d7eb8..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/11-final-audit/evidence/final-audit-summary.md +++ /dev/null @@ -1,73 +0,0 @@ -# Final Audit Evidence - -## Prior Sprint Audit Result - -The final audit rechecked Sprint 01 through Sprint 10 using each sprint's -`closeout.md` and evidence markdown. - -Audit result: - -1. every Sprint 01 through Sprint 10 directory has a `closeout.md` -2. every audited closeout records a passing `sprint_closeout: pass` -3. no audited closeout records an active blocker or exception -4. every audited sprint evidence folder contains at least one substantive - markdown evidence document - -Sprint-by-sprint completion summary: - -1. Sprint 01 through Sprint 04: workflow lifecycle, references, helper, - template, and regression baseline completed and evidenced -2. Sprint 05 through Sprint 07: inventory alignment, deterministic integrity - validators, and local-to-CI parity completed and evidenced -3. Sprint 08 through Sprint 10: generated-output placeholder contract, - packaging policy, and warning-only freshness or portability guidance - completed and evidenced - -## Final Repository State Check - -The final audit revalidated the authoritative repository surfaces that this -initiative hardened: - -1. `AGENTS.md` -2. `README.md` -3. `plugin.json` -4. `.github/plugin/marketplace.json` -5. `.agents/skills/` -6. `.github/agents/` -7. `.ub-workflows/` - -Observed final-state highlights: - -1. root registry and public inventory stay aligned on 10 skills and 4 custom agents -2. packaging policy is explicit and keeps `agents/openai.yaml` optional -3. freshness review is explicit and warning-only by design -4. `task check` remains the blocking local parity baseline -5. generated-output placeholder enforcement exists without treating advisory - workflow prompts as failures - -## Follow-Up Decision - -User response recorded during Sprint 11: - -1. no follow-up audits requested -2. no follow-up refactors requested - -## Final Validation Proof - -Passed commands: - -1. `task check` -2. `uv run python .agents/skills/ub-workflow/scripts/check_scaffold_placeholders.py ./.ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening --strict` -3. `uv run python .agents/skills/ub-workflow/scripts/scaffold_initiative.py archive ./.ub-workflows/initiatives/2026-04-16-repository-self-governance-hardening --dry-run` - -## Archive Readiness Result - -Archive was not executed. - -Archive readiness result: - -1. final audit state is complete -2. `retained-note.md` is written -3. follow-up decisions are explicit -4. archive remains an explicit human review decision rather than an automatic - side effect diff --git a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/11-final-audit/sprint.md b/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/11-final-audit/sprint.md deleted file mode 100644 index f70d29d..0000000 --- a/.ub-workflows/archive/2026-04-16-repository-self-governance-hardening/sprints/11-final-audit/sprint.md +++ /dev/null @@ -1,133 +0,0 @@ -# Sprint PRD - -## Summary - -Run the final initiative audit for repository self-governance hardening only -after all prior implementation sprints have either passed or been explicitly -deferred with recorded reasons. This sprint is the completion checkpoint that -verifies no roadmap scope was silently skipped, synchronized artifacts and -validation outputs are current, follow-up decisions are captured, and the -initiative is ready for retained-note completion and explicit archive review. - -## Scope - -1. Verify that every prior sprint outcome claimed in closeout records actually - landed in the repository or was explicitly deferred. -2. Confirm that the canonical documentation, tests, metadata, and workflow - artifacts are synchronized with the shipped behavior. -3. Run the final validation baseline and record any explicit deferments. -4. Ask the user whether follow-up audits or refactors are wanted and record the - answer. -5. Prepare `./retained-note.md` and the final initiative status so archive can - remain an explicit human decision rather than an automatic transition. - -## Dependencies - -1. This sprint depends on Sprint 10 and, by extension, on all prior - implementation sprint closeouts and evidence folders. -2. Use `./prd.md` sections 20 through 25, the roadmap completion condition, and - every prior sprint `closeout.md` as the authoritative audit inputs. -3. Use the final state of `./README.md`, `./roadmap.md`, and - `./retained-note.md` as the initiative control surfaces for closure. - -## Repository Truth At Sprint Start - -1. This sprint cannot rely on assumptions about implementation state; it must - assemble truth from the final repository state plus the closeout and - evidence records produced by prior sprints. -2. The roadmap requires that all implementation sprints have closeout records, - that synchronized artifacts be current, and that follow-up decisions be - explicit before the initiative is considered complete. -3. `./retained-note.md` is not yet written and therefore becomes a required - audit output rather than a pre-existing dependency. -4. Archive is not part of this sprint's execution path unless the user - explicitly requests it after reviewing the final audit output. - -## Chosen Path - -Run an evidence-driven final audit that starts from prior sprint closeouts, -verifies the final repository state directly, records any explicit deferrals, -then prepares retained-note and archive-readiness outputs for human review. -This keeps completion honest and prevents archive from becoming an implicit side -effect of passing tests alone. - -## Rejected Alternative - -Treat a green local test run as sufficient proof that the initiative is done -and move directly to archive. - -Pros: - -1. Fastest path to closure. -2. Low coordination overhead. - -Cons: - -1. Does not prove roadmap scope was actually executed. -2. Can miss unsynchronized docs, retained-note gaps, or unrecorded follow-up - decisions. -3. Conflicts with the roadmap's explicit human review checkpoint before - archive. - -## Affected Areas - -1. `./README.md` -2. `./roadmap.md` -3. `./retained-note.md` -4. Every prior sprint directory under `./sprints/` as audit inputs via - `closeout.md` and `./evidence/` -5. Any repository files touched by prior sprints that must be re-validated as - part of final synchronization checks - -## Validation Plan - -1. Run the final local validation baseline, expected to be the closest local CI - mirror in place by the end of the initiative, and record the exact command - and outcome in the closeout. -2. Re-open `./README.md`, `./roadmap.md`, and the retained note to confirm the - final state, next action, and completion narrative are synchronized. -3. Audit every prior sprint `closeout.md` and evidence folder for missing - validation, missing documentation-sync statements, or unresolved blockers. -4. Record the answer to the follow-up audit or refactor question in both the - closeout and retained note. -5. For the Level 1 `lean` governance bridge, record the final completion gate, - any remaining exception state, and why archive is or is not ready. - -## Exit Criteria - -1. Every roadmap item has either a passing closeout or an explicit recorded - deferral with rationale. -2. Final validation results, synchronized-artifact checks, and follow-up - decisions are recorded and traceable. -3. `./retained-note.md` is ready and the initiative is prepared for explicit - human review before any archive action. - -## Final Audit Checklist - -Use this checklist only when this sprint is the final audit sprint. - -- [ ] roadmap scope was actually executed or explicitly deferred -- [ ] no material work was silently skipped -- [ ] initiative-level validation is recorded and traceable -- [ ] relevant documentation and synchronized artifacts reflect the shipped behavior -- [ ] follow-up audit or refactor decisions were captured -- [ ] `retained-note.md` is ready to record the final state - -## Handoff Expectation - -There is no next implementation sprint after this one. After the final audit, -the operator should read the completed `closeout.md`, `./retained-note.md`, and -updated `./README.md`, answer the follow-up audit or refactor question if it is -still open, and archive the initiative only on explicit human approval. - -## Definition Of Done - -This sprint is done only when all of the following are true: - -1. planned functionality is complete or explicitly blocked -2. known in-scope issues are documented -3. required validation is run or explicitly deferred -4. relevant documentation and synchronized artifacts are updated or explicitly marked unchanged -5. validation evidence is recorded and traceable -6. governance bridge requirements are satisfied or explicitly marked not applicable -7. closeout is current and resumable diff --git a/.ub-workflows/initiatives/AGENTS.md b/.ub-workflows/initiatives/AGENTS.md deleted file mode 100644 index 37f261c..0000000 --- a/.ub-workflows/initiatives/AGENTS.md +++ /dev/null @@ -1,50 +0,0 @@ -# Sprint Operations — AGENTS.md - -## Scope - -Applies to this operations root and its descendants. - -## Local Rules - -- `operation-guide.md` is the formal workflow contract for this operations root. -- `roadmap.md` is the small live progress document for an initiative and should - be the first file read when resuming work. -- Each sprint `sprint.md` must be a standalone sprint PRD that can be executed - without reopening the master `prd.md`. -- After importing a master PRD, stop and produce a durable `roadmap.md` before - initializing sprint folders. -- Initialize sprint folders only after `roadmap_ready: pass`. -- After sprint initialization, stop and wait for an explicit user request - before executing the active sprint. -- The roadmap must end with a final audit step before the initiative can close. -- Validation and documentation are completion gates, not optional follow-up work. -- Keep paths relative to the current operations root or initiative root when - practical. - -## Resume Order For Agents - -When resuming work inside one initiative root, read in this order: - -1. `./roadmap.md` -2. the most recent sprint `closeout.md` -3. the active or next sprint `sprint.md` -4. `./README.md` -5. `./prd.md` only if additional initiative-level context is still needed - -## Update Discipline - -- Update `roadmap.md` whenever sprint status changes. -- Update the initiative `README.md` whenever phase, blockers, or next action changes. -- Keep `closeout.md` current before pausing or handing off. -- Do not initialize sprint folders until `roadmap.md` is complete enough to - stand in for plan output without chat history. -- Initialize sprint folders from the canonical `ub-workflow` sprint template - when building the roadmap-derived sprint set. -- Execute only the user-requested active sprint in one invocation, then stop - after closeout and roadmap updates. -- Do not treat a sprint as complete until its validation results, evidence, and - relevant documentation updates are recorded or explicitly marked unchanged. -- Do not treat an initiative as complete until final validation, retained-note, - and documentation synchronization checks are recorded. -- Before treating an initiative as complete, record whether the user wants any - follow-up audits or refactors. diff --git a/.ub-workflows/initiatives/README.md b/.ub-workflows/initiatives/README.md deleted file mode 100644 index 7552407..0000000 --- a/.ub-workflows/initiatives/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# Initiative Index - -This directory is the canonical initiative index for work managed under the -repository operations root. - -Start with `operation-guide.md` for the durable workflow SOP, then open the -initiative root you want to work on. - -Use each initiative's `roadmap.md` as the small live progress document when -resuming work. - -If you want to bootstrap a new initiative quickly, use -`uv run python .agents/skills/ub-workflow/scripts/scaffold_initiative.py create --prd-source <path-to-prd>`. - -If you want a bounded planning artifact without opening a full initiative, use -`uv run python .agents/skills/ub-workflow/scripts/scaffold_initiative.py create-spec <slug>`. - -## Active Initiative Roots - -1. `initiatives/2026-04-25-skill-principle-documentation-uplift` - -## Current State - -1. The operation guide lives here as the canonical SOP for initiative work. -2. The scaffold helper can bootstrap the parent operations root and create new initiative roots or lightweight specs on demand. -3. The scaffold helper uses the skill's internal initiative, lightweight-spec, and sprint templates instead of requiring copied local scaffolding directories. -4. Historical initiative roots live under `../archive/`. - -## Active Lightweight Specs - -1. `none` - diff --git a/.ub-workflows/initiatives/operation-guide.md b/.ub-workflows/initiatives/operation-guide.md deleted file mode 100644 index 293a190..0000000 --- a/.ub-workflows/initiatives/operation-guide.md +++ /dev/null @@ -1,206 +0,0 @@ -# Initiative Operation Guide - -<!-- #region Purpose And Use --> -## Purpose - -This document defines a strict, reusable standard operating procedure for large -or risky initiatives that cannot be executed reliably from chat history alone. - -Use this SOP when work requires: - -1. planning and R&D before implementation -2. a self-contained PRD that can be executed later -3. multiple stop-and-resume execution sprints -4. deterministic evidence and explicit gate states -5. a durable retained summary after completion - -This SOP is written to be usable by a PM, an engineer, and an AI agent with the -same source of truth. - -## Typical Ownership Model - -The most common workflow is: - -1. a human authors the initial PRD -2. a human or AI agent scaffolds a dated initiative root and copies that PRD into `./prd.md` -3. a human or AI agent refines the PRD and produces a durable `roadmap.md` -4. the human reviews and explicitly approves the roadmap -5. sprint folders are initialized only after the roadmap is approved -6. the workflow stops until the human explicitly requests the active sprint -7. execution happens one sprint at a time, with a human review checkpoint after each sprint, until the initiative is complete - -This SOP supports other authorship patterns, but it assumes the initial product -or engineering intent has a clear human owner. - -## When To Use This SOP - -Use this SOP for work that has at least one of these properties: - -1. spans more than one working session -2. changes behavior, architecture, or operating model -3. needs explicit option analysis or governance review -4. needs evidence-backed handoffs between sprints -5. must be resumable without relying on prior chat context - -Do not use this SOP for small, single-session fixes where a lightweight task -note is enough. - -## Non-Negotiable Rules - -1. One initiative uses one initiative root directory. -2. The PRD must be self-contained and execution-ready before sprinting starts. -3. Every sprint must be stop-resume safe. -4. Evidence, planning, and closeout are separate artifacts. -5. Gate states are always `pass`, `fail`, or `blocked`. -6. Exceptions must be explicit, temporary, and owned. -7. The retained note is the durable record after completion. -8. Chat history is never the system of record. -<!-- #endregion Purpose And Use --> - -<!-- #region Operating Model --> -## Operating Model - -This SOP defines a four-phase lifecycle. - -### Phase 1: Plan And Author The PRD - -Goal: turn research and intent into one self-contained PRD that is ready to be -executed later by a different operator or agent. - -### Phase 2: Plan And Approve The Roadmap - -Goal: turn the approved PRD into one durable roadmap that can initialize sprint -folders without relying on chat history. - -### Phase 3: Execute In Ordered Sprints - -Goal: split the PRD into bounded sprints that can be paused, resumed, audited, -and handed off without loss of context. - -### Phase 4: Final Audit And Durable Retention - -Goal: finish the roadmap with a mandatory final audit, confirm completeness and -synchronization, ask for any follow-up audits or refactors, then replace bulky -temporary execution detail with a concise retained note. - -## Lifecycle Gates - -This SOP uses lifecycle gates in addition to any repository-specific merge or -release gates. - -| Gate | Meaning | Allowed States | -| ---- | ------- | -------------- | -| `prd_ready` | The PRD is execution-ready and sprint planning may begin | `pass`, `fail`, `blocked` | -| `roadmap_ready` | The roadmap is execution-ready and sprint initialization may begin | `pass`, `fail`, `blocked` | -| `sprint_closeout` | A sprint has enough evidence and handoff detail to pause or continue | `pass`, `fail`, `blocked` | -| `initiative_complete` | The initiative has a retained note and a validated completion baseline | `pass`, `fail`, `blocked` | - -`roadmap_ready: pass` is human-owned in this workflow. The agent may recommend -approval after surfacing the roadmap review checklist, but the human must -explicitly approve the roadmap before that gate is set. - -State intent: - -- `pass`: required controls are satisfied -- `fail`: the work was evaluated and one or more required controls failed -- `blocked`: required controls cannot be satisfied yet because prerequisites, - evidence, or approvals are missing -<!-- #endregion Operating Model --> - -<!-- #region Canonical Layout --> -## Canonical Directory Layout - -Store every initiative under one canonical root. - -## Path Portability Rules - -Write all operational instructions relative to the current operations root when -possible. - -Preferred path style inside this SOP and inside initiative files: - -1. from this initiative index, use `./<yyyy-mm-dd>-<slug>/...` -2. from an initiative root, use `./prd.md`, `./sprints/`, `./retained-note.md` -3. use repo-root-relative paths only when referencing legacy material outside - the current operations root - -Generic pattern: - -```text -<operations-root>/ - archive/ - initiatives/ - AGENTS.md - README.md - operation-guide.md - <yyyy-mm-dd>-<initiative-slug>/ - AGENTS.md - README.md - prd.md - roadmap.md - research/ - sprint-template/ - sprints/ - 01-<sprint-slug>/ - sprint.md - closeout.md - evidence/ - ./ - 2026-03-27-example-initiative/ - exceptions/ - retained-note.md -``` - -The generated operations root does not need a checked-in `initiative-template/` -copy. The scaffold helper uses the skill's internal canonical templates to -create initiative roots and sprint skeletons on demand. - -## Directory Contract - -### `README.md` - -The operator-facing status file for the initiative root. - -Use it as the root summary and entry point. - -`roadmap.md` is the smaller live progress document. - -### `prd.md` - -The self-contained initiative definition. It must remain understandable without -opening research or sprint files. - -### `research/` - -Optional source captures, exploratory notes, and supporting material from the -planning phase. The PRD may cite it, but must not depend on it for core intent. - -### `sprints/` - -The execution packs. Each sprint gets its own numbered directory so planning, -evidence, and closeout stay co-located. - -Use the sprint template when initializing all sprint directories from the master -roadmap. Do not initialize sprint directories until `roadmap_ready: pass`. -Initialization prepares execution; it does not start sprint work automatically. - -### `exceptions/` - -Optional explicit exception records. If no exceptions are active, this folder -may be omitted. - -### `retained-note.md` - -The durable completion record for the initiative. - -## Naming Rules - -1. Initiative roots use `YYYY-MM-DD-slug`. -2. Sprint directories use `NN-slug` with zero-padded ordering. -3. Evidence directories live inside the owning sprint directory. -4. Singular control files keep fixed names: `README.md`, `AGENTS.md`, `prd.md`, - `roadmap.md`, `retained-note.md`, `sprint.md`, and `closeout.md`. -5. Do not scatter PRDs, evidence, and retained notes across unrelated folders. -6. Prefer relative paths inside operation artifacts unless cross-root references - are necessary. -<!-- #endregion Canonical Layout --> diff --git a/AGENTS.md b/AGENTS.md index 7610abe..b39e181 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -186,3 +186,15 @@ trigger rules inside the skill before producing work that depends on them. ## Instructions *No `.instructions.md` files defined yet.* + +<!-- BEGIN UB-WORKFLOW ROOT ROUTING --> +## UB Workflow Routing + +- Before substantial work, read `.ub-workflows/status.md`. +- For non-trivial source work, read `SOURCE_ATLAS.md` and then the nearest relevant folder `AGENTS.md`. +- Use `.ub-workflows/vision.md` when product direction matters. +- Use `.ub-workflows/WORKFLOW_ATLAS.md` for workflow-artifact routing. +- Use `.ub-workflows/SOURCE_PACK_ATLAS.md` before opening retained source packs. +- When forecast pressure appears, present options and tradeoffs, then wait for explicit operator decision before expanding scope. +- Keep reusable workflow mechanics in the shared `ub-workflow` skill; keep repo overlays focused on local facts, boundaries, and validation commands. +<!-- END UB-WORKFLOW ROOT ROUTING --> diff --git a/SOURCE_ATLAS.md b/SOURCE_ATLAS.md new file mode 100644 index 0000000..0134390 --- /dev/null +++ b/SOURCE_ATLAS.md @@ -0,0 +1,42 @@ +# Source Atlas + +This file routes source-code work before agents read implementation files. It is seeded once by `ub-workflow` bootstrap from visible project roots and then maintained when source boundaries change. + +## First-Read Order + +For non-trivial source work: + +1. Root `AGENTS.md`. +2. `.ub-workflows/status.md`. +3. `SOURCE_ATLAS.md`. +4. Nearest relevant folder `AGENTS.md` when one exists. +5. Selected source files and tests. +6. `.ub-workflows/vision.md` only when product direction matters. + +Do not read unrelated folder guidance unless the task crosses that boundary. + +## Map Use Rule + +Module maps are routing aids, not source truth. Use them to choose files to open first, then inspect source and tests with fast local search before changing behavior. If source ownership changes, update this atlas in the same change. + +## Detected Source Routes + +- `tests/`: start at `tests/`. +- `docs/`: start at `docs/AGENTS.md`. +- `scripts/`: start at `scripts/`. + +## Workflow Route + +- Workflow state, waves, discoveries, initiatives, sprints, and source packs: start at `.ub-workflows/WORKFLOW_ATLAS.md`, then `.ub-workflows/AGENTS.md`. + +## Local Guidance Policy + +Local `AGENTS.md` files should answer only what the folder owns, when work starts there, local boundaries, what to inspect before editing, likely tests, and what to avoid. Add local guidance only when a folder has a meaningful responsibility boundary, rule set, or repeated navigation cost. + +## Source Route Note + +Before editing, identify the owning folder, local guidance read, expected source files, expected tests, and boundaries intentionally avoided. + +## Maintenance + +Update this file and the nearest relevant folder `AGENTS.md` when a change adds, removes, renames, or moves a source boundary, plugin lane, public API area, runtime/protocol/host responsibility, major package, or test topology. diff --git a/Taskfile.yml b/Taskfile.yml index b86ee1b..e1c2cb9 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -7,7 +7,6 @@ vars: YAML_TARGETS: >- Taskfile.yml .pre-commit-config.yaml .yamllint.yaml .github/workflows/*.yml .agents/skills/ub-governance/references/high-risk-paths.yaml - .agents/skills/ub-workflow/assets/initiative-template/exceptions/exception-template.yaml tasks: sync: diff --git a/tests/skills/ub-workflow/test_scaffold_initiative.py b/tests/skills/ub-workflow/test_scaffold_initiative.py deleted file mode 100644 index 7617681..0000000 --- a/tests/skills/ub-workflow/test_scaffold_initiative.py +++ /dev/null @@ -1,1383 +0,0 @@ -from __future__ import annotations - -from argparse import Namespace -import importlib.util -from pathlib import Path -import subprocess -import sys -import tempfile -import unittest -from unittest import mock - - -def find_repo_root() -> Path: - for candidate in Path(__file__).resolve().parents: - if (candidate / "pyproject.toml").exists() and (candidate / ".agents").exists(): - return candidate - msg = "Could not locate repository root for workflow tests" - raise RuntimeError(msg) - - -PROJECT_ROOT = find_repo_root() -SCRIPT = PROJECT_ROOT / ".agents" / "skills" / "ub-workflow" / "scripts" / "scaffold_initiative.py" -CHECK_SCRIPT = PROJECT_ROOT / ".agents" / "skills" / "ub-workflow" / "scripts" / "check_scaffold_placeholders.py" -PYTHON_BIN = sys.executable - -SCRIPT_SPEC = importlib.util.spec_from_file_location("ub_workflow_scaffold_initiative", SCRIPT) -assert SCRIPT_SPEC is not None and SCRIPT_SPEC.loader is not None -SCRIPT_MODULE = importlib.util.module_from_spec(SCRIPT_SPEC) -sys.modules[SCRIPT_SPEC.name] = SCRIPT_MODULE -SCRIPT_SPEC.loader.exec_module(SCRIPT_MODULE) - - -def run_cmd(args: list[str]) -> subprocess.CompletedProcess[str]: - return subprocess.run( - args, - cwd=str(PROJECT_ROOT), - text=True, - capture_output=True, - check=False, - ) - - -class ScaffoldInitiativeScriptTests(unittest.TestCase): - def test_create_bootstraps_ops_root_and_scaffolds_blank_initiative(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / ".ub-workflows" - - result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - "my-new-initiative", - "--ops-root", - str(ops_root), - "--date", - "2026-04-01", - ] - ) - - self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr) - target = ops_root / "initiatives" / "2026-04-01-my-new-initiative" - self.assertTrue((ops_root / "initiatives" / "README.md").exists()) - self.assertTrue((ops_root / "initiatives" / "operation-guide.md").exists()) - self.assertTrue((ops_root / "initiatives" / "AGENTS.md").exists()) - self.assertTrue((target / "README.md").exists()) - self.assertTrue((target / "roadmap.md").exists()) - self.assertFalse((target / "sprint-template").exists()) - - root_readme = (ops_root / "initiatives" / "README.md").read_text(encoding="utf-8") - readme = (target / "README.md").read_text(encoding="utf-8") - roadmap = (target / "roadmap.md").read_text(encoding="utf-8") - - self.assertIn("`initiatives/2026-04-01-my-new-initiative`", root_readme) - self.assertIn("`operation-guide.md`", root_readme) - self.assertNotIn("`user-guide.md`", root_readme) - self.assertIn("My New Initiative", readme) - self.assertIn("2026-04-01", readme) - self.assertIn("Scaffold valid for PRD authoring; PRD import pending", readme) - self.assertIn("`prd_ready: blocked`", readme) - self.assertIn("unassigned", readme) - self.assertIn("Master PRD imported into `./prd.md`", roadmap) - self.assertIn("- Next sprint: `define after roadmap approval`", roadmap) - - def test_create_uses_prd_source_slug_and_copies_prd_without_rewriting(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - prd_source = Path(tmp) / "service-accounts-prd.md" - prd_body = "# Service Accounts PRD\n\nThis content must be copied as-is.\n" - prd_source.write_text(prd_body, encoding="utf-8") - - result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - "--ops-root", - str(ops_root), - "--prd-source", - str(prd_source), - "--date", - "2026-04-03", - ] - ) - - self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr) - - target = ops_root / "initiatives" / "2026-04-03-service-accounts-prd" - self.assertEqual((target / "prd.md").read_text(encoding="utf-8"), prd_body) - - readme = (target / "README.md").read_text(encoding="utf-8") - self.assertIn("Scaffold valid for PRD review; roadmap planning pending", readme) - self.assertIn("`prd_ready: blocked`", readme) - self.assertIn("Do not initialize sprint directories until `roadmap_ready: pass`", readme) - - def test_create_supports_imported_prd_state(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - prd_source = Path(tmp) / "parser-modernization-prd.md" - prd_source.write_text("# Parser Modernization\n", encoding="utf-8") - - result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - "--ops-root", - str(ops_root), - "--prd-source", - str(prd_source), - "--initiative-name", - "Parser Modernization", - "--owner", - "Platform Team", - "--prd-imported", - "--date", - "2026-04-02", - ] - ) - - self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr) - - target = ops_root / "initiatives" / "2026-04-02-parser-modernization" - readme = (target / "README.md").read_text(encoding="utf-8") - - self.assertIn("Parser Modernization", readme) - self.assertIn("Platform Team", readme) - self.assertIn("Scaffold valid for roadmap planning; roadmap approval pending", readme) - self.assertIn("`prd_ready: pass`", readme) - - def test_prepare_sprints_ignores_legacy_local_sprint_template(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - initiative_root = ops_root / "initiatives" / "2026-04-02-parser-modernization" - - create_result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - str(initiative_root), - "--ops-root", - str(ops_root), - "--date", - "2026-04-02", - "--initiative-name", - "Parser Modernization", - ] - ) - self.assertEqual(create_result.returncode, 0, msg=create_result.stdout + create_result.stderr) - self.assertFalse((initiative_root / "sprint-template").exists()) - - legacy_template_root = initiative_root / "sprint-template" - legacy_template_root.mkdir(parents=True, exist_ok=True) - (legacy_template_root / "sprint.md").write_text( - "# Sprint PRD\n\nLEGACY LOCAL TEMPLATE SHOULD NOT BE USED.\n", - encoding="utf-8", - ) - (legacy_template_root / "closeout.md").write_text("# Sprint Closeout\n", encoding="utf-8") - (legacy_template_root / "decision-log.md").write_text("# Sprint Decision Log\n", encoding="utf-8") - (legacy_template_root / "evidence").mkdir(exist_ok=True) - - (initiative_root / "roadmap.md").write_text( - """# Sprint Roadmap - -Status: planned - -## Overall Checklist - -- [x] Master PRD imported into `./prd.md` -- [x] Master roadmap generated from `./prd.md` -- [x] Roadmap reviewed and approved with `roadmap_ready: pass` -- [ ] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template - -## Sprint Sequence - -- [ ] Sprint 01 - Define Contract - - Path: `./sprints/01-define-contract/sprint.md` - - Goal: Define the contract - - Depends on: `none` - - Validation focus: Contract review - - Subtasks: - - [ ] Draft the contract - - Evidence folder: `./sprints/01-define-contract/evidence/` -""", - encoding="utf-8", - ) - - readme_path = initiative_root / "README.md" - readme_path.write_text( - readme_path.read_text(encoding="utf-8").replace("`prd_ready: blocked`", "`roadmap_ready: pass`"), - encoding="utf-8", - ) - - result = run_cmd([PYTHON_BIN, str(SCRIPT), "prepare-sprints", str(initiative_root)]) - - self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr) - sprint_text = (initiative_root / "sprints" / "01-define-contract" / "sprint.md").read_text(encoding="utf-8") - self.assertIn("## Machine-Derived Context", sprint_text) - self.assertNotIn("LEGACY LOCAL TEMPLATE SHOULD NOT BE USED", sprint_text) - - def test_prepare_sprints_renders_roadmap_metadata_into_sprint_prds(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - initiative_root = ops_root / "initiatives" / "2026-04-02-parser-modernization" - - create_result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - str(initiative_root), - "--ops-root", - str(ops_root), - "--date", - "2026-04-02", - "--initiative-name", - "Parser Modernization", - ] - ) - self.assertEqual(create_result.returncode, 0, msg=create_result.stdout + create_result.stderr) - - (initiative_root / "roadmap.md").write_text( - """# Sprint Roadmap - -Status: planned - -## Overall Checklist - -- [x] Master PRD imported into `./prd.md` -- [x] Master roadmap generated from `./prd.md` -- [x] Roadmap reviewed and approved with `roadmap_ready: pass` -- [ ] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template - -## Current Position - -- Current sprint: `none` -- Last completed sprint: `none` -- Next sprint: `define after roadmap approval` -- Resume from: `review or generate roadmap from ./prd.md` -- Active blockers: `none` - -## Sprint Sequence - -- [ ] Sprint 01 - Define Contract - - Path: `./sprints/01-define-contract/sprint.md` - - Goal: Define the contract - so every later sprint inherits one stable workflow baseline - - Depends on: `none` - - Validation focus: Contract review - with lifecycle and gate consistency checks - - Subtasks: - - [ ] Draft the contract - and capture the shared gate vocabulary - - [ ] Review the contract with stakeholders - - Evidence folder: `./sprints/01-define-contract/evidence/` - -- [ ] Sprint 02 - Wire Runtime - - Path: `./sprints/02-wire-runtime/sprint.md` - - Goal: Wire runtime behavior - - Depends on: `Sprint 01 - Define Contract` - - Validation focus: Engine integration tests - - Subtasks: - - [ ] Implement runtime changes - - Evidence folder: `./sprints/02-wire-runtime/evidence/` - -## Final Audit Step - -1. Confirm completeness. -""", - encoding="utf-8", - ) - - readme_path = initiative_root / "README.md" - readme_path.write_text( - readme_path.read_text(encoding="utf-8").replace("`prd_ready: blocked`", "`roadmap_ready: pass`"), - encoding="utf-8", - ) - self.assertFalse((initiative_root / "sprint-template").exists()) - - result = run_cmd([PYTHON_BIN, str(SCRIPT), "prepare-sprints", str(initiative_root)]) - - self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr) - first_sprint = (initiative_root / "sprints" / "01-define-contract" / "sprint.md").read_text(encoding="utf-8") - second_sprint = (initiative_root / "sprints" / "02-wire-runtime" / "sprint.md").read_text(encoding="utf-8") - readme = readme_path.read_text(encoding="utf-8") - roadmap = (initiative_root / "roadmap.md").read_text(encoding="utf-8") - - self.assertIn("## Machine-Derived Context", first_sprint) - self.assertIn( - "- Goal: Define the contract so every later sprint inherits one stable workflow baseline", - first_sprint, - ) - self.assertIn( - "- Validation focus: Contract review with lifecycle and gate consistency checks", - first_sprint, - ) - self.assertIn("- [ ] Draft the contract and capture the shared gate vocabulary", first_sprint) - self.assertNotIn("REPLACE_", first_sprint) - self.assertIn("PENDING_HANDOFF:", second_sprint) - self.assertIn("`sprint_content_ready: pass`", readme) - self.assertIn("Sprint pack prepared, awaiting Sprint 01 execution", readme) - self.assertIn( - "- [x] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template", - roadmap, - ) - - def test_prepare_sprints_preserves_non_placeholder_sprint_docs(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - initiative_root = ops_root / "initiatives" / "2026-04-02-parser-modernization" - - create_result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - str(initiative_root), - "--ops-root", - str(ops_root), - "--date", - "2026-04-02", - "--initiative-name", - "Parser Modernization", - ] - ) - self.assertEqual(create_result.returncode, 0, msg=create_result.stdout + create_result.stderr) - - (initiative_root / "roadmap.md").write_text( - """# Sprint Roadmap - -Status: planned - -## Overall Checklist - -- [x] Master PRD imported into `./prd.md` -- [x] Master roadmap generated from `./prd.md` -- [x] Roadmap reviewed and approved with `roadmap_ready: pass` -- [ ] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template - -## Sprint Sequence - -- [ ] Sprint 01 - Define Contract - - Path: `./sprints/01-define-contract/sprint.md` - - Goal: Define the contract - - Depends on: `none` - - Validation focus: Contract review - - Subtasks: - - [ ] Draft the contract - - Evidence folder: `./sprints/01-define-contract/evidence/` -""", - encoding="utf-8", - ) - - readme_path = initiative_root / "README.md" - readme_path.write_text( - readme_path.read_text(encoding="utf-8").replace("`prd_ready: blocked`", "`roadmap_ready: pass`"), - encoding="utf-8", - ) - - init_result = run_cmd([PYTHON_BIN, str(SCRIPT), "init-sprints", str(initiative_root)]) - self.assertEqual(init_result.returncode, 0, msg=init_result.stdout + init_result.stderr) - - sprint_path = initiative_root / "sprints" / "01-define-contract" / "sprint.md" - sprint_path.write_text( - "# Sprint PRD\n\n## Summary\n\nPrepared custom sprint content.\n", - encoding="utf-8", - ) - - result = run_cmd([PYTHON_BIN, str(SCRIPT), "prepare-sprints", str(initiative_root)]) - - self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr) - self.assertEqual( - sprint_path.read_text(encoding="utf-8"), - "# Sprint PRD\n\n## Summary\n\nPrepared custom sprint content.\n", - ) - self.assertIn("preserved", result.stdout) - - def test_prepare_sprints_accepts_recorded_roadmap_approval_after_gate_advances(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - initiative_root = ops_root / "initiatives" / "2026-04-02-parser-modernization" - - create_result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - str(initiative_root), - "--ops-root", - str(ops_root), - "--date", - "2026-04-02", - "--initiative-name", - "Parser Modernization", - ] - ) - self.assertEqual(create_result.returncode, 0, msg=create_result.stdout + create_result.stderr) - - (initiative_root / "roadmap.md").write_text( - """# Sprint Roadmap - -Status: generated - -## Overall Checklist - -- [x] Master PRD imported into `./prd.md` -- [x] Master roadmap generated from `./prd.md` -- [x] Roadmap reviewed and approved with `roadmap_ready: pass` -- [x] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template - -## Sprint Sequence - -- [ ] Sprint 01 - Define Contract - - Path: `./sprints/01-define-contract/sprint.md` - - Goal: Define the contract - - Depends on: `none` - - Validation focus: Contract review - - Subtasks: - - [ ] Draft the contract - - Evidence folder: `./sprints/01-define-contract/evidence/` -""", - encoding="utf-8", - ) - - readme_path = initiative_root / "README.md" - readme_path.write_text( - readme_path.read_text(encoding="utf-8").replace("`prd_ready: blocked`", "`sprint_closeout: pass`"), - encoding="utf-8", - ) - - result = run_cmd([PYTHON_BIN, str(SCRIPT), "prepare-sprints", str(initiative_root)]) - - self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr) - self.assertTrue((initiative_root / "sprints" / "01-define-contract" / "sprint.md").exists()) - - def test_prepare_sprints_blocks_without_roadmap_approval(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - initiative_root = ops_root / "initiatives" / "2026-04-02-parser-modernization" - - create_result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - str(initiative_root), - "--ops-root", - str(ops_root), - "--date", - "2026-04-02", - "--initiative-name", - "Parser Modernization", - ] - ) - self.assertEqual(create_result.returncode, 0, msg=create_result.stdout + create_result.stderr) - - (initiative_root / "roadmap.md").write_text( - """# Sprint Roadmap - -Status: planned - -## Overall Checklist - -- [x] Master PRD imported into `./prd.md` -- [x] Master roadmap generated from `./prd.md` -- [ ] Roadmap reviewed and approved with `roadmap_ready: pass` -- [ ] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template - -## Sprint Sequence - -- [ ] Sprint 01 - Define Contract - - Path: `./sprints/01-define-contract/sprint.md` - - Goal: Define the contract - - Depends on: `none` - - Validation focus: Contract review - - Subtasks: - - [ ] Draft the contract - - Evidence folder: `./sprints/01-define-contract/evidence/` -""", - encoding="utf-8", - ) - - result = run_cmd([PYTHON_BIN, str(SCRIPT), "prepare-sprints", str(initiative_root)]) - - self.assertEqual(result.returncode, 1, msg=result.stdout + result.stderr) - self.assertIn("Sprint preparation blocked because the roadmap is not ready", result.stderr) - self.assertIn("roadmap_ready: pass", result.stderr) - - def test_resume_order_for_placeholder_sprint_falls_back_to_prd(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - initiative_root = ops_root / "initiatives" / "2026-04-02-parser-modernization" - - create_result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - str(initiative_root), - "--ops-root", - str(ops_root), - "--date", - "2026-04-02", - "--initiative-name", - "Parser Modernization", - ] - ) - self.assertEqual(create_result.returncode, 0, msg=create_result.stdout + create_result.stderr) - - roadmap_path = initiative_root / "roadmap.md" - roadmap_path.write_text( - """# Sprint Roadmap - -Status: generated - -## Overall Checklist - -- [x] Master PRD imported into `./prd.md` -- [x] Master roadmap generated from `./prd.md` -- [x] Roadmap reviewed and approved with `roadmap_ready: pass` -- [x] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template - -## Current Position - -- Current sprint: `none` -- Last completed sprint: `none` -- Next sprint: `Sprint 01 - Define Contract` -- Resume from: `sprints/01-define-contract/sprint.md` -- Active blockers: `none` - -## Sprint Sequence - -- [ ] Sprint 01 - Define Contract - - Path: `./sprints/01-define-contract/sprint.md` - - Goal: Define the contract - - Depends on: `none` - - Validation focus: Contract review - - Subtasks: - - [ ] Draft the contract - - Evidence folder: `./sprints/01-define-contract/evidence/` -""", - encoding="utf-8", - ) - - readme_path = initiative_root / "README.md" - readme_path.write_text( - readme_path.read_text(encoding="utf-8").replace("`prd_ready: blocked`", "`roadmap_ready: pass`"), - encoding="utf-8", - ) - - init_result = run_cmd([PYTHON_BIN, str(SCRIPT), "init-sprints", str(initiative_root)]) - self.assertEqual(init_result.returncode, 0, msg=init_result.stdout + init_result.stderr) - - ordered = SCRIPT_MODULE.resolve_resume_file_order(initiative_root) - - self.assertEqual( - [path.resolve().relative_to(initiative_root.resolve()).as_posix() for path in ordered], - ["roadmap.md", "sprints/01-define-contract/sprint.md", "README.md", "prd.md"], - ) - - def test_resume_order_for_later_prepared_sprint_uses_prior_closeout_without_prd(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - initiative_root = ops_root / "initiatives" / "2026-04-02-parser-modernization" - - create_result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - str(initiative_root), - "--ops-root", - str(ops_root), - "--date", - "2026-04-02", - "--initiative-name", - "Parser Modernization", - ] - ) - self.assertEqual(create_result.returncode, 0, msg=create_result.stdout + create_result.stderr) - - roadmap_path = initiative_root / "roadmap.md" - roadmap_path.write_text( - """# Sprint Roadmap - -Status: generated - -## Overall Checklist - -- [x] Master PRD imported into `./prd.md` -- [x] Master roadmap generated from `./prd.md` -- [x] Roadmap reviewed and approved with `roadmap_ready: pass` -- [x] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template - -## Current Position - -- Current sprint: `none` -- Last completed sprint: `Sprint 01 - Define Contract` -- Next sprint: `Sprint 02 - Wire Runtime` -- Resume from: `sprints/02-wire-runtime/sprint.md` -- Active blockers: `none` - -## Sprint Sequence - -- [x] Sprint 01 - Define Contract - - Path: `./sprints/01-define-contract/sprint.md` - - Goal: Define the contract - - Depends on: `none` - - Validation focus: Contract review - - Subtasks: - - [ ] Draft the contract - - Evidence folder: `./sprints/01-define-contract/evidence/` - -- [ ] Sprint 02 - Wire Runtime - - Path: `./sprints/02-wire-runtime/sprint.md` - - Goal: Wire runtime behavior - - Depends on: `Sprint 01 - Define Contract` - - Validation focus: Engine integration tests - - Subtasks: - - [ ] Implement runtime changes - - Evidence folder: `./sprints/02-wire-runtime/evidence/` -""", - encoding="utf-8", - ) - - readme_path = initiative_root / "README.md" - readme_path.write_text( - readme_path.read_text(encoding="utf-8").replace("`prd_ready: blocked`", "`sprint_content_ready: pass`"), - encoding="utf-8", - ) - - prepare_result = run_cmd([PYTHON_BIN, str(SCRIPT), "prepare-sprints", str(initiative_root)]) - self.assertEqual(prepare_result.returncode, 0, msg=prepare_result.stdout + prepare_result.stderr) - - (initiative_root / "sprints" / "01-define-contract" / "closeout.md").write_text( - "# Sprint Closeout\n\n## handoff_note\n\nReady for Sprint 02.\n", - encoding="utf-8", - ) - - ordered = SCRIPT_MODULE.resolve_resume_file_order( - initiative_root, - initiative_root / "sprints" / "02-wire-runtime" / "sprint.md", - ) - - self.assertEqual( - [path.resolve().relative_to(initiative_root.resolve()).as_posix() for path in ordered], - [ - "roadmap.md", - "sprints/01-define-contract/closeout.md", - "sprints/02-wire-runtime/sprint.md", - "README.md", - ], - ) - - def test_archive_blocks_without_archive_review_gate(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - initiative_root = ops_root / "initiatives" / "2026-04-02-parser-modernization" - - create_result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - str(initiative_root), - "--ops-root", - str(ops_root), - "--initiative-name", - "Parser Modernization", - ] - ) - self.assertEqual(create_result.returncode, 0, msg=create_result.stdout + create_result.stderr) - - (initiative_root / "README.md").write_text( - """# Initiative Status - -## Snapshot - -| Field | Value | -| ----- | ----- | -| Initiative | Parser Modernization | -| Imported on | 2026-04-02 | -| Current phase | Final audit complete, awaiting archive review | -| Current gate | `sprint_closeout: pass` | -| Roadmap status | `complete` | -| Active sprint | `none` | -| Last completed sprint | `Final Audit - Confirm Completion` | -| Next step | `archive review needed` | -| Blockers | `none` | - -## Validation Pointers - -Complete. -""", - encoding="utf-8", - ) - (initiative_root / "roadmap.md").write_text( - """# Sprint Roadmap - -Status: complete - -## Overall Checklist - -- [x] Master PRD imported into `./prd.md` -- [x] Master roadmap generated from `./prd.md` -- [x] Roadmap reviewed and approved with `roadmap_ready: pass` -- [x] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template -- [x] Sprint execution started -- [x] All sprint closeouts completed -- [x] Final audit completed as the last roadmap item -- [x] Follow-up audit or refactor decision recorded -- [x] `./retained-note.md` written -""", - encoding="utf-8", - ) - (initiative_root / "retained-note.md").write_text( - """# Retained Note - -## Outcome - -Completed successfully. -""", - encoding="utf-8", - ) - - result = run_cmd([PYTHON_BIN, str(SCRIPT), "archive", str(initiative_root), "--ops-root", str(ops_root)]) - - self.assertEqual(result.returncode, 1, msg=result.stdout + result.stderr) - self.assertIn("archive_ready: pass", result.stderr) - self.assertTrue(initiative_root.exists()) - - def test_init_sprints_creates_all_roadmap_directories_and_updates_status_files(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - initiative_root = ops_root / "initiatives" / "2026-04-02-parser-modernization" - - create_result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - str(initiative_root), - "--ops-root", - str(ops_root), - "--date", - "2026-04-02", - "--initiative-name", - "Parser Modernization", - ] - ) - self.assertEqual(create_result.returncode, 0, msg=create_result.stdout + create_result.stderr) - - roadmap_path = initiative_root / "roadmap.md" - roadmap_path.write_text( - """# Sprint Roadmap - -Status: planned - -## Overall Checklist - -- [x] Master PRD imported into `./prd.md` -- [x] Master roadmap generated from `./prd.md` -- [x] Roadmap reviewed and approved with `roadmap_ready: pass` -- [ ] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template - -## Current Position - -- Current sprint: `none` -- Last completed sprint: `none` -- Next sprint: `define after roadmap approval` -- Resume from: `review or generate roadmap from ./prd.md` -- Active blockers: `none` - -## Sprint Sequence - -- [ ] Sprint 01 - Define Contract - - Path: `./sprints/01-define-contract/sprint.md` - - Goal: Define the contract - - Depends on: `none` - - Validation focus: Contract review - - Subtasks: - - [ ] Draft the contract - - Evidence folder: `./sprints/01-define-contract/evidence/` - -- [ ] Sprint 02 - Wire Runtime - - Path: `./sprints/02-wire-runtime/sprint.md` - - Goal: Wire runtime behavior - - Depends on: `Sprint 01 - Define Contract` - - Validation focus: Engine integration tests - - Subtasks: - - [ ] Implement runtime changes - - Evidence folder: `./sprints/02-wire-runtime/evidence/` - -- [ ] Final Audit - Confirm Completion - - Path: `./sprints/03-final-audit/sprint.md` - - Goal: Confirm initiative completeness - - Depends on: `all prior implementation sprints` - - Validation focus: Final initiative audit - - Subtasks: - - [ ] Confirm final closeout state - - Evidence folder: `./sprints/03-final-audit/evidence/` - -## Final Audit Step - -1. Confirm completeness. -""", - encoding="utf-8", - ) - - readme_path = initiative_root / "README.md" - readme_path.write_text( - readme_path.read_text(encoding="utf-8").replace("`prd_ready: blocked`", "`roadmap_ready: pass`"), - encoding="utf-8", - ) - self.assertFalse((initiative_root / "sprint-template").exists()) - - result = run_cmd([PYTHON_BIN, str(SCRIPT), "init-sprints", str(initiative_root)]) - - self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr) - self.assertTrue((initiative_root / "sprints" / "01-define-contract" / "sprint.md").exists()) - self.assertTrue((initiative_root / "sprints" / "01-define-contract" / "closeout.md").exists()) - self.assertTrue((initiative_root / "sprints" / "01-define-contract" / "evidence").exists()) - self.assertTrue((initiative_root / "sprints" / "02-wire-runtime" / "sprint.md").exists()) - self.assertTrue((initiative_root / "sprints" / "03-final-audit" / "sprint.md").exists()) - - readme = (initiative_root / "README.md").read_text(encoding="utf-8") - roadmap = roadmap_path.read_text(encoding="utf-8") - self.assertIn("Roadmap approved, sprint initialization complete", readme) - self.assertIn("Open the sprint-start checkpoint for Sprint 01 - Define Contract", readme) - self.assertIn("wait for the single later approval before execution", readme) - self.assertIn("`roadmap_ready: pass`", readme) - self.assertIn("Status: generated", roadmap) - self.assertIn( - "- [x] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template", - roadmap, - ) - self.assertIn("- Next sprint: `Sprint 01 - Define Contract`", roadmap) - - def test_init_sprints_blocks_until_roadmap_ready_gate_passes(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - initiative_root = ops_root / "initiatives" / "2026-04-02-parser-modernization" - - create_result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - str(initiative_root), - "--ops-root", - str(ops_root), - "--date", - "2026-04-02", - "--initiative-name", - "Parser Modernization", - ] - ) - self.assertEqual(create_result.returncode, 0, msg=create_result.stdout + create_result.stderr) - - (initiative_root / "roadmap.md").write_text( - """# Sprint Roadmap - -Status: planned - -## Overall Checklist - -- [x] Master PRD imported into `./prd.md` -- [x] Master roadmap generated from `./prd.md` -- [ ] Roadmap reviewed and approved with `roadmap_ready: pass` -- [ ] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template - -## Sprint Sequence - -- [ ] Sprint 01 - Define Contract - - Path: `./sprints/01-define-contract/sprint.md` - - Goal: Define the contract - - Depends on: `none` - - Validation focus: Contract review - - Subtasks: - - [ ] Draft the contract - - Evidence folder: `./sprints/01-define-contract/evidence/` -""", - encoding="utf-8", - ) - - result = run_cmd([PYTHON_BIN, str(SCRIPT), "init-sprints", str(initiative_root)]) - - self.assertEqual(result.returncode, 1, msg=result.stdout + result.stderr) - self.assertIn("roadmap is not ready", result.stderr) - self.assertIn("`roadmap_ready: pass`", result.stderr) - - def test_archive_blocks_incomplete_initiatives(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - initiative_root = ops_root / "initiatives" / "2026-04-02-parser-modernization" - - create_result = run_cmd( - [PYTHON_BIN, str(SCRIPT), "create", str(initiative_root), "--ops-root", str(ops_root)] - ) - self.assertEqual(create_result.returncode, 0, msg=create_result.stdout + create_result.stderr) - - result = run_cmd([PYTHON_BIN, str(SCRIPT), "archive", str(initiative_root), "--ops-root", str(ops_root)]) - - self.assertEqual(result.returncode, 1, msg=result.stdout + result.stderr) - self.assertIn("Archive blocked because the initiative is not complete", result.stderr) - self.assertTrue(initiative_root.exists()) - - def test_archive_moves_completed_initiative_and_syncs_root_readme(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - initiative_root = ops_root / "initiatives" / "2026-04-02-parser-modernization" - - create_result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - str(initiative_root), - "--ops-root", - str(ops_root), - "--initiative-name", - "Parser Modernization", - ] - ) - self.assertEqual(create_result.returncode, 0, msg=create_result.stdout + create_result.stderr) - - (initiative_root / "README.md").write_text( - """# Initiative Status - -## Snapshot - -| Field | Value | -| ----- | ----- | -| Initiative | Parser Modernization | -| Imported on | 2026-04-02 | -| Current phase | Complete | -| Current gate | `initiative_complete: pass` | -| Roadmap status | `complete` | -| Active sprint | `none` | -| Last completed sprint | `Sprint 02 - Wire Runtime` | -| Next step | `none` | -| Blockers | `none` | - -## Validation Pointers - -Complete. -""", - encoding="utf-8", - ) - (initiative_root / "roadmap.md").write_text( - """# Sprint Roadmap - -Status: complete - -## Overall Checklist - -- [x] Master PRD imported into `./prd.md` -- [x] Master roadmap generated from `./prd.md` -- [x] Roadmap reviewed and approved with `roadmap_ready: pass` -- [x] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template -- [x] Sprint execution started -- [x] All sprint closeouts completed -- [x] Final audit completed as the last roadmap item -- [x] Follow-up audit or refactor decision recorded -- [x] `./retained-note.md` written -""", - encoding="utf-8", - ) - (initiative_root / "retained-note.md").write_text( - """# Retained Note - -## Outcome - -Completed successfully. -""", - encoding="utf-8", - ) - - result = run_cmd([PYTHON_BIN, str(SCRIPT), "archive", str(initiative_root), "--ops-root", str(ops_root)]) - - self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr) - self.assertFalse(initiative_root.exists()) - self.assertTrue((ops_root / "archive" / "2026-04-02-parser-modernization").exists()) - root_readme = (ops_root / "initiatives" / "README.md").read_text(encoding="utf-8") - self.assertNotIn("`initiatives/2026-04-02-parser-modernization`", root_readme) - - def test_script_blocks_rerun_against_populated_target(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - target = Path(tmp) / "existing-initiative" - target.mkdir(parents=True, exist_ok=True) - (target / "README.md").write_text("existing", encoding="utf-8") - - result = run_cmd([PYTHON_BIN, str(SCRIPT), str(target)]) - - self.assertEqual(result.returncode, 1, msg=result.stdout + result.stderr) - self.assertIn("already contains files", result.stderr) - self.assertEqual((target / "README.md").read_text(encoding="utf-8"), "existing") - - def test_dry_run_reports_without_writing_files(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - - result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - "dry-run-initiative", - "--ops-root", - str(ops_root), - "--dry-run", - ] - ) - - self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr) - self.assertIn("dry-run: operations root would be", result.stdout) - self.assertFalse(ops_root.exists()) - - def test_create_reports_placeholder_summary_for_generated_artifacts(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / ".ub-workflows" - - result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - "my-new-initiative", - "--ops-root", - str(ops_root), - "--date", - "2026-04-01", - ] - ) - - self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr) - self.assertIn("placeholder summary:", result.stdout) - self.assertIn("phase status: scaffold is valid for PRD authoring.", result.stdout) - self.assertIn("prd.md", result.stdout) - self.assertIn("roadmap.md", result.stdout) - - def test_create_spec_reports_phase_status_for_generated_artifacts(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / ".ub-workflows" - target = ops_root / "specs" / "2026-04-01-workflow-gap-note" - - result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create-spec", - "workflow-gap-note", - "--ops-root", - str(ops_root), - "--date", - "2026-04-01", - ] - ) - - self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr) - self.assertTrue((target / "spec.md").exists()) - self.assertIn(f"scaffolded lightweight spec at {target.resolve().as_posix()}", result.stdout) - self.assertIn("phase status: scaffold is valid for spec authoring.", result.stdout) - self.assertIn("placeholder summary:", result.stdout) - - def test_check_scaffold_placeholders_strict_fails_for_placeholder_only_sprint_shells(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - initiative_root = ops_root / "initiatives" / "2026-04-02-parser-modernization" - - create_result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - str(initiative_root), - "--ops-root", - str(ops_root), - "--date", - "2026-04-02", - "--initiative-name", - "Parser Modernization", - ] - ) - self.assertEqual(create_result.returncode, 0, msg=create_result.stdout + create_result.stderr) - - roadmap_path = initiative_root / "roadmap.md" - roadmap_path.write_text( - """# Sprint Roadmap - -Status: planned - -## Overall Checklist - -- [x] Master PRD imported into `./prd.md` -- [x] Master roadmap generated from `./prd.md` -- [x] Roadmap reviewed and approved with `roadmap_ready: pass` -- [ ] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template - -## Current Position - -- Current sprint: `none` -- Last completed sprint: `none` -- Next sprint: `define after roadmap approval` -- Resume from: `review or generate roadmap from ./prd.md` -- Active blockers: `none` - -## Sprint Sequence - -- [ ] Sprint 01 - Define Contract - - Path: `./sprints/01-define-contract/sprint.md` - - Goal: Define the contract - - Depends on: `none` - - Validation focus: Contract review - - Subtasks: - - [ ] Draft the contract - - Evidence folder: `./sprints/01-define-contract/evidence/` -""", - encoding="utf-8", - ) - - readme_path = initiative_root / "README.md" - readme_path.write_text( - readme_path.read_text(encoding="utf-8").replace("`prd_ready: blocked`", "`roadmap_ready: pass`"), - encoding="utf-8", - ) - - init_result = run_cmd([PYTHON_BIN, str(SCRIPT), "init-sprints", str(initiative_root)]) - self.assertEqual(init_result.returncode, 0, msg=init_result.stdout + init_result.stderr) - - result = run_cmd([PYTHON_BIN, str(CHECK_SCRIPT), str(initiative_root), "--strict"]) - - self.assertEqual(result.returncode, 1, msg=result.stdout + result.stderr) - self.assertIn("sprints/01-define-contract/sprint.md", result.stdout) - self.assertIn("REPLACE_SPRINT_TITLE", result.stdout) - - def test_prepare_sprints_strict_placeholders_passes_with_advisory_findings(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - initiative_root = ops_root / "initiatives" / "2026-04-02-parser-modernization" - - create_result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - str(initiative_root), - "--ops-root", - str(ops_root), - "--date", - "2026-04-02", - "--initiative-name", - "Parser Modernization", - ] - ) - self.assertEqual(create_result.returncode, 0, msg=create_result.stdout + create_result.stderr) - - (initiative_root / "roadmap.md").write_text( - """# Sprint Roadmap - -Status: planned - -## Overall Checklist - -- [x] Master PRD imported into `./prd.md` -- [x] Master roadmap generated from `./prd.md` -- [x] Roadmap reviewed and approved with `roadmap_ready: pass` -- [ ] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template - -## Current Position - -- Current sprint: `none` -- Last completed sprint: `none` -- Next sprint: `define after roadmap approval` -- Resume from: `review or generate roadmap from ./prd.md` -- Active blockers: `none` - -## Sprint Sequence - -- [ ] Sprint 01 - Define Contract - - Path: `./sprints/01-define-contract/sprint.md` - - Goal: Define the contract - so every later sprint inherits one stable workflow baseline - - Depends on: `none` - - Validation focus: Contract review - with lifecycle and gate consistency checks - - Subtasks: - - [ ] Draft the contract - and capture the shared gate vocabulary - - Evidence folder: `./sprints/01-define-contract/evidence/` - -- [ ] Sprint 02 - Wire Runtime - - Path: `./sprints/02-wire-runtime/sprint.md` - - Goal: Wire runtime behavior - - Depends on: `Sprint 01 - Define Contract` - - Validation focus: Engine integration tests - - Subtasks: - - [ ] Implement runtime changes - - Evidence folder: `./sprints/02-wire-runtime/evidence/` - -## Final Audit Step - -1. Confirm completeness. -""", - encoding="utf-8", - ) - - readme_path = initiative_root / "README.md" - readme_path.write_text( - readme_path.read_text(encoding="utf-8").replace("`prd_ready: blocked`", "`roadmap_ready: pass`"), - encoding="utf-8", - ) - - result = run_cmd( - [PYTHON_BIN, str(SCRIPT), "prepare-sprints", str(initiative_root), "--strict-placeholders"] - ) - - self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr) - self.assertIn("placeholder summary:", result.stdout) - self.assertIn("advisory", result.stdout) - self.assertIn("PENDING_HANDOFF:", result.stdout) - - def test_prepare_sprints_fails_when_canonical_sprint_template_is_missing(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - initiative_root = ops_root / "initiatives" / "2026-04-02-parser-modernization" - - create_result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - str(initiative_root), - "--ops-root", - str(ops_root), - "--date", - "2026-04-02", - "--initiative-name", - "Parser Modernization", - ] - ) - self.assertEqual(create_result.returncode, 0, msg=create_result.stdout + create_result.stderr) - - (initiative_root / "roadmap.md").write_text( - """# Sprint Roadmap - -Status: planned - -## Overall Checklist - -- [x] Master PRD imported into `./prd.md` -- [x] Master roadmap generated from `./prd.md` -- [x] Roadmap reviewed and approved with `roadmap_ready: pass` -- [ ] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template - -## Sprint Sequence - -- [ ] Sprint 01 - Define Contract - - Path: `./sprints/01-define-contract/sprint.md` - - Goal: Define the contract - - Depends on: `none` - - Validation focus: Contract review - - Subtasks: - - [ ] Draft the contract - - Evidence folder: `./sprints/01-define-contract/evidence/` -""", - encoding="utf-8", - ) - - readme_path = initiative_root / "README.md" - readme_path.write_text( - readme_path.read_text(encoding="utf-8").replace("`prd_ready: blocked`", "`roadmap_ready: pass`"), - encoding="utf-8", - ) - - missing_template_root = Path(tmp) / "missing-sprint-template" - with ( - mock.patch.object(SCRIPT_MODULE, "CANONICAL_SPRINT_TEMPLATE_ROOT", missing_template_root), - self.assertRaisesRegex(ValueError, "Canonical `ub-workflow` sprint template is missing or invalid") as exc, - ): - SCRIPT_MODULE.command_prepare_sprints( - Namespace( - initiative_root=str(initiative_root), - strict_placeholders=False, - dry_run=False, - ) - ) - - self.assertIn(missing_template_root.as_posix(), str(exc.exception)) - - def test_placeholder_checker_ignores_code_examples_and_quoted_placeholder_prose(self) -> None: - with tempfile.TemporaryDirectory() as tmp: - ops_root = Path(tmp) / "ops" - initiative_root = ops_root / "initiatives" / "2026-04-02-parser-modernization" - - create_result = run_cmd( - [ - PYTHON_BIN, - str(SCRIPT), - "create", - str(initiative_root), - "--ops-root", - str(ops_root), - "--date", - "2026-04-02", - "--initiative-name", - "Parser Modernization", - ] - ) - self.assertEqual(create_result.returncode, 0, msg=create_result.stdout + create_result.stderr) - - (initiative_root / "prd.md").write_text( - """# Example PRD - -## Example output - -```text -Unresolved placeholders: -- REPLACE_OWNER (optional) -``` - -## Notes - -Treat any `Replace with...` or `REPLACE_` string anywhere in the repository as an unconditional failure. -""", - encoding="utf-8", - ) - (initiative_root / "roadmap.md").write_text( - """# Sprint Roadmap - -Status: generated - -## Overall Checklist - -- [x] Master PRD imported into `./prd.md` -- [x] Master roadmap generated from `./prd.md` -- [x] Roadmap reviewed and approved with `roadmap_ready: pass` -- [x] All sprint folders initialized under `./sprints/` from the canonical `ub-workflow` sprint template -""", - encoding="utf-8", - ) - (initiative_root / "README.md").write_text( - """# Initiative Status - -## Snapshot - -| Field | Value | -| ----- | ----- | -| Initiative | Parser Modernization | -| Current gate | `roadmap_ready: pass` | -""", - encoding="utf-8", - ) - - result = run_cmd([PYTHON_BIN, str(CHECK_SCRIPT), str(initiative_root), "--strict"]) - - self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr) - self.assertIn("no unresolved generated-artifact placeholders", result.stdout) - - -if __name__ == "__main__": - unittest.main(verbosity=2) diff --git a/tests/skills/ub-workflow/test_scaffold_workflow.py b/tests/skills/ub-workflow/test_scaffold_workflow.py new file mode 100644 index 0000000..0a8a820 --- /dev/null +++ b/tests/skills/ub-workflow/test_scaffold_workflow.py @@ -0,0 +1,211 @@ +from __future__ import annotations + +from pathlib import Path +import subprocess +import sys +import tempfile +import unittest + + +def find_repo_root() -> Path: + for candidate in Path(__file__).resolve().parents: + if (candidate / "pyproject.toml").exists() and (candidate / ".agents").exists(): + return candidate + msg = "Could not locate repository root for workflow tests" + raise RuntimeError(msg) + + +PROJECT_ROOT = find_repo_root() +SCRIPT = PROJECT_ROOT / ".agents" / "skills" / "ub-workflow" / "scripts" / "scaffold_workflow.py" +CHECK_SCRIPT = ( + PROJECT_ROOT / ".agents" / "skills" / "ub-workflow" / "scripts" / "check_scaffold_placeholders.py" +) +PYTHON_BIN = sys.executable + + +def run_cmd(args: list[str]) -> subprocess.CompletedProcess[str]: + return subprocess.run( + args, + cwd=str(PROJECT_ROOT), + text=True, + capture_output=True, + check=False, + ) + + +class ScaffoldWorkflowScriptTests(unittest.TestCase): + def run_ok(self, args: list[str]) -> subprocess.CompletedProcess[str]: + result = run_cmd(args) + self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr) + return result + + def bootstrap_project(self, tmp_root: Path) -> tuple[Path, Path]: + project_root = tmp_root / "project" + ops_root = project_root / ".ub-workflows" + self.run_ok([PYTHON_BIN, str(SCRIPT), "bootstrap", "--ops-root", str(ops_root)]) + return project_root, ops_root + + def create_wave(self, ops_root: Path, wave_id: str = "w01", slug: str = "onboarding") -> Path: + result = self.run_ok( + [PYTHON_BIN, str(SCRIPT), "create-wave", wave_id, slug, "--ops-root", str(ops_root)] + ) + return Path(result.stdout.strip()) + + def create_initiative(self, wave_root: Path, slug: str = "first-feature") -> Path: + result = self.run_ok([PYTHON_BIN, str(SCRIPT), "create-initiative", str(wave_root), slug]) + return Path(result.stdout.strip()).parent + + def test_bootstrap_creates_modern_operations_root_and_source_atlas(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + project_root, ops_root = self.bootstrap_project(Path(tmp)) + + self.assertTrue((ops_root / "AGENTS.md").exists()) + self.assertTrue((ops_root / "WORKFLOW_ATLAS.md").exists()) + self.assertTrue((ops_root / "SOURCE_PACK_ATLAS.md").exists()) + self.assertTrue((ops_root / "source-packs" / ".gitkeep").exists()) + self.assertTrue((ops_root / "waves" / ".gitkeep").exists()) + self.assertTrue((project_root / "SOURCE_ATLAS.md").exists()) + + root_agents = (project_root / "AGENTS.md").read_text(encoding="utf-8") + self.assertIn("BEGIN UB-WORKFLOW ROOT ROUTING", root_agents) + self.assertIn(".ub-workflows/status.md", root_agents) + + def test_create_wave_and_initiative_outputs_normalized_layout(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + _, ops_root = self.bootstrap_project(Path(tmp)) + + wave_root = self.create_wave(ops_root) + initiative_root = self.create_initiative(wave_root) + + self.assertEqual(wave_root.name, "w01-onboarding") + self.assertEqual(initiative_root.name, "i01-first-feature") + self.assertFalse((ops_root / "waves" / ".gitkeep").exists()) + self.assertTrue((wave_root / "wave.md").exists()) + self.assertTrue((wave_root / "initiatives" / "i01-first-feature").exists()) + self.assertTrue((initiative_root / "initiative.md").exists()) + self.assertTrue((initiative_root / "roadmap.md").exists()) + self.assertTrue((initiative_root / "index.md").exists()) + self.assertTrue((initiative_root / "discoveries" / ".gitkeep").exists()) + self.assertTrue((initiative_root / "sprints" / ".gitkeep").exists()) + self.assertFalse((initiative_root / "sprint-template").exists()) + + initiative = (initiative_root / "initiative.md").read_text(encoding="utf-8") + self.assertIn("# Initiative: First Feature", initiative) + self.assertIn("## Forecast And Appetite", initiative) + + def test_discovery_source_pack_and_sprint_commands_create_expected_artifacts(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + _, ops_root = self.bootstrap_project(Path(tmp)) + wave_root = self.create_wave(ops_root) + initiative_root = self.create_initiative(wave_root) + + discovery_result = self.run_ok( + [PYTHON_BIN, str(SCRIPT), "create-discovery", str(initiative_root), "route-check"] + ) + source_pack_result = self.run_ok( + [ + PYTHON_BIN, + str(SCRIPT), + "create-source-pack", + str(wave_root), + "research-note", + "--date", + "2026-05-29", + ] + ) + sprint_result = self.run_ok( + [PYTHON_BIN, str(SCRIPT), "prepare-sprint", str(initiative_root), "alpha"] + ) + + discovery_path = Path(discovery_result.stdout.strip()) + source_pack_root = Path(source_pack_result.stdout.strip()) + sprint_root = Path(sprint_result.stdout.strip()) + + self.assertEqual(discovery_path.name, "w01-i01-d01-route-check.md") + self.assertTrue((source_pack_root / "00-readme.md").exists()) + self.assertEqual(source_pack_root.name, "2026-05-29-research-note") + self.assertTrue((sprint_root / "sprint.md").exists()) + self.assertTrue((sprint_root / "decision-log.md").exists()) + self.assertTrue((sprint_root / "closeout.md").exists()) + self.assertTrue((sprint_root / "evidence" / "index.md").exists()) + self.assertTrue((sprint_root / "evidence" / ".gitignore").exists()) + + sprint = (sprint_root / "sprint.md").read_text(encoding="utf-8") + self.assertIn("# Sprint: Alpha", sprint) + self.assertIn("Deliver alpha.", sprint) + self.assertNotIn("REPLACE_SPRINT_TITLE", sprint) + + def test_prepare_sprint_all_materializes_unchecked_roadmap_candidates(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + _, ops_root = self.bootstrap_project(Path(tmp)) + wave_root = self.create_wave(ops_root) + initiative_root = self.create_initiative(wave_root) + (initiative_root / "roadmap.md").write_text( + "# Initiative Roadmap\n\n" + "## Adaptive Plan\n\n" + "- [x] Already complete.\n" + "- [ ] Alpha Slice\n" + "- [ ] `Beta Slice`\n", + encoding="utf-8", + ) + + result = self.run_ok( + [PYTHON_BIN, str(SCRIPT), "prepare-sprint", str(initiative_root), "fallback", "--all"] + ) + created = [Path(line) for line in result.stdout.splitlines() if line.strip()] + + self.assertEqual(len(created), 2) + self.assertEqual(created[0].name, "w01-i01-s01-sprint-alpha-slice") + self.assertEqual(created[1].name, "w01-i01-s02-sprint-beta-slice") + self.assertIn("# Sprint: Alpha Slice", (created[0] / "sprint.md").read_text(encoding="utf-8")) + self.assertIn("# Sprint: Beta Slice", (created[1] / "sprint.md").read_text(encoding="utf-8")) + + def test_archive_initiative_moves_wave_local_and_restores_gitkeep(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + _, ops_root = self.bootstrap_project(Path(tmp)) + wave_root = self.create_wave(ops_root) + initiative_root = self.create_initiative(wave_root) + + result = self.run_ok([PYTHON_BIN, str(SCRIPT), "archive-initiative", str(initiative_root)]) + archive_root = Path(result.stdout.strip()) + + self.assertFalse(initiative_root.exists()) + self.assertEqual(archive_root, wave_root / "archive" / "i01-first-feature") + self.assertTrue((archive_root / "initiative.md").exists()) + self.assertTrue((wave_root / "initiatives" / ".gitkeep").exists()) + + def test_placeholder_checker_fails_strict_for_unresolved_generated_artifacts(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + _, ops_root = self.bootstrap_project(Path(tmp)) + wave_root = self.create_wave(ops_root) + initiative_root = self.create_initiative(wave_root) + self.run_ok([PYTHON_BIN, str(SCRIPT), "prepare-sprint", str(initiative_root), "alpha"]) + + result = run_cmd([PYTHON_BIN, str(CHECK_SCRIPT), str(initiative_root), "--strict"]) + + self.assertEqual(result.returncode, 1, msg=result.stdout + result.stderr) + self.assertIn("placeholder summary:", result.stdout) + self.assertIn("required", result.stdout) + self.assertIn("sprints/w01-i01-s01-sprint-alpha/sprint.md", result.stdout) + + def test_placeholder_checker_ignores_code_fence_examples(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + workflow_root = Path(tmp) / "i01-placeholder-demo" + workflow_root.mkdir(parents=True) + (workflow_root / "initiative.md").write_text( + "# Placeholder Demo\n\n" + "```text\n" + "REPLACE_OWNER\n" + "Replace with sample prose.\n" + "```\n", + encoding="utf-8", + ) + + result = run_cmd([PYTHON_BIN, str(CHECK_SCRIPT), str(workflow_root), "--strict"]) + + self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr) + self.assertIn("no unresolved generated-artifact placeholders", result.stdout) + + +if __name__ == "__main__": + unittest.main(verbosity=2)