diff --git a/work-package/activities/14-complete.yaml b/work-package/activities/14-complete.yaml index 5dd6b1e4..f56b3b65 100644 --- a/work-package/activities/14-complete.yaml +++ b/work-package/activities/14-complete.yaml @@ -7,9 +7,11 @@ variables: - branch_name - changed_files - component_git_dir + - component_name - host_repo_path - is_review_mode - issue_number + - issue_platform - planning_folder_path - pr_number - problem_complexity @@ -31,6 +33,25 @@ variables: type: string description: Path to the close-out document. defaultValue: "" + - name: current_deferred_item + type: object + description: The deferred-items register row under consideration during the raise loop. + - name: deferred_items + type: string + description: The deferred-items register with each approved row's Follow-up cell carrying the issue it was raised as. + defaultValue: "" + - name: has_unraised_deferred_items + type: boolean + description: Whether the register holds at least one row naming no issue yet. + defaultValue: false + - name: open_deferred_items + type: array + description: Register rows whose Follow-up cell holds no issue link, each carrying its ID, item and rationale. + defaultValue: [] + - name: raise_current_deferred_item + type: boolean + description: Whether the raise gate approved the row under consideration. Both gate options set it, so each pass through the loop decides on its own row. + defaultValue: false - name: publishable_files type: array description: Every changed file under `{planning_folder_path}`, including `README.md`, the linked report artifacts, `review-summary.md`, `session.json` and `.session-token`. @@ -52,6 +73,39 @@ steps: id: finalize-test-plan technique: finalize-documentation::finalize-test-plan when: is_review_mode != true + - kind: technique + id: collect-deferred-items + technique: raise-deferred-items::collect + when: is_review_mode != true + - kind: loop + id: deferred-item-raise-loop + name: Deferred Item Raise Loop + loopType: forEach + variable: current_deferred_item + over: open_deferred_items + when: is_review_mode != true && has_unraised_deferred_items == true + steps: + - kind: checkpoint + id: deferred-item-raise#{current_deferred_item.id} + message: "Deferred item {current_deferred_item.id}: {current_deferred_item.item} — deferred because {current_deferred_item.rationale}" + blocking: true + options: + - id: raise + label: Raise an issue + description: Create a tracker issue for this item and link it from the register row + effect: + setVariable: + raise_current_deferred_item: true + - id: skip + label: Leave unraised + description: Keep the row open with its dash, for a later package to raise + effect: + setVariable: + raise_current_deferred_item: false + - kind: technique + id: raise-deferred-item + technique: raise-deferred-items::raise + when: raise_current_deferred_item == true - kind: technique id: create-complete-doc technique: finalize-documentation::create-complete-doc diff --git a/work-package/resources/deferred-items.md b/work-package/resources/deferred-items.md index 482af4bb..09e6fa34 100644 --- a/work-package/resources/deferred-items.md +++ b/work-package/resources/deferred-items.md @@ -27,4 +27,4 @@ The register is the one canonical home for work consciously deferred **out of sc - **One row per item, updated in place** — when a deferred item is raised as a tracker issue, add the link to its Follow-up cell; when it is picked up, mark the row `→ #[issue]` rather than deleting it. - **Created lazily, unprefixed** — create the register as bare `deferred-items.md` when the first deferred item appears; a run that defers nothing has no register. Any activity may be the one that defers first, so the register has no owning activity and takes no `artifactPrefix`. - **Link, don't restate** — producers (requirements Deferred scope, assumption deferrals, review-finding deferrals, COMPLETE.md) record one pointer line to this register; the row here is the single statement of the item. -- **Issue creation reads this register** — deferred-item issues are raised from register rows, carrying the row ID for traceability. +- **Completion raises the open rows** — the `complete` activity reads the register, asks the run about each row naming no issue yet, and raises the approved ones through [raise-deferred-items](../techniques/raise-deferred-items/TECHNIQUE.md), writing each issue's link into its own row. A row the run skips keeps its dash and stays open for a later package. Each issue carries its row ID, so the issue and the row name each other. diff --git a/work-package/techniques/raise-deferred-items/TECHNIQUE.md b/work-package/techniques/raise-deferred-items/TECHNIQUE.md new file mode 100644 index 00000000..089e10e8 --- /dev/null +++ b/work-package/techniques/raise-deferred-items/TECHNIQUE.md @@ -0,0 +1,46 @@ +--- +metadata: + version: 1.0.0 +--- + +## Capability + +Deferred-items register rows carried into the issue tracker — the open rows found, and an issue raised and linked for each row the run approves. + +## Inputs + +### planning_folder_path + +The work package's planning folder, which holds the deferred-items register when the run deferred anything. + +## Outputs + +### deferred_items + +The deferred-items [register](../../resources/deferred-items.md#template) with each approved row's Follow-up cell carrying the issue it was raised as. + +#### artifact + +`deferred-items.md` + +#### audience + +`human` + +## Rules + +### register-is-the-source + +An issue is raised from a register row and carries that row's ID, so the issue and the row each name the other. A deferral that reaches the tracker without a row has no record of why it was out of scope. + +### one-issue-per-row + +A row acquires at most one issue. A row whose Follow-up cell already holds a link is raised already, and a second issue for it would split the item's history across two tickets. + +### row-survives-the-raise + +Raising rewrites the Follow-up cell and nothing else. The item, its rationale and its ID stay as the deferring activity wrote them, so the register still says why the item was set aside rather than only where it went. + +### approval-precedes-creation + +An issue appears in a tracker other people read, so each row is raised only where the run approved that row. A row the run skipped keeps its dash and stays open for a later package to raise. diff --git a/work-package/techniques/raise-deferred-items/collect.md b/work-package/techniques/raise-deferred-items/collect.md new file mode 100644 index 00000000..bc74fa0c --- /dev/null +++ b/work-package/techniques/raise-deferred-items/collect.md @@ -0,0 +1,34 @@ +--- +metadata: + version: 1.0.0 +--- + +## Capability + +The deferred-items register read for rows that name no issue yet. + +## Outputs + +### open_deferred_items + +The register rows whose Follow-up cell holds no issue link, each carrying `id`, `item` and `rationale` from the row as the deferring activity wrote them. Empty when the register does not exist, or when every row is raised already. + +### has_unraised_deferred_items + +Boolean gate — true when `{open_deferred_items}` holds at least one row. + +## Protocol + +### 1. Locate the Register + +- Read `deferred-items.md` in `{planning_folder_path}`. + > The register is created lazily, so a run that deferred nothing has none. Set `{open_deferred_items}` empty and `{has_unraised_deferred_items}` false, and report that the run deferred nothing rather than reporting a missing file as a fault. + +### 2. Select the Unraised Rows + +- Take every row of the register table whose Follow-up cell holds a dash rather than a link, and record it in `{open_deferred_items}` with its ID, its item text and its rationale. +- Set `{has_unraised_deferred_items}` from whether that set holds anything. + +### 3. Report What Is Outstanding + +- State the count and each row's ID and item in one line apiece, so the run sees what it is being asked about before it is asked. diff --git a/work-package/techniques/raise-deferred-items/raise.md b/work-package/techniques/raise-deferred-items/raise.md new file mode 100644 index 00000000..0f6b4fce --- /dev/null +++ b/work-package/techniques/raise-deferred-items/raise.md @@ -0,0 +1,54 @@ +--- +metadata: + version: 1.0.0 +--- + +## Capability + +An issue raised in the tracker for one approved deferred-item row, and the row updated to name it. + +## Inputs + +### current_deferred_item + +The register row the raise gate approved, carrying its ID, its item text and the rationale the deferring activity recorded. + +### issue_platform + +The tracker the work package's own issue lives in — github or jira — so a deferred item is raised where its package is tracked. + +### component_name + +Basename of the component the work package targets, which scopes the issue the same way the package's own issue is scoped. + +## Outputs + +### deferred_items + +The [register](../../resources/deferred-items.md#template) with this row's Follow-up cell carrying the issue it was raised as. + +#### artifact + +`deferred-items.md` + +#### audience + +`human` + +## Protocol + +### 1. Draft the Issue + +- Draft a title from `{current_deferred_item}`'s item text, and a body carrying the item, the rationale the register gives for it being out of scope, and the row's ID. +- Scope the issue to `{component_name}`, and state the problem the deferral leaves open rather than a solution for it, per the issue-writing rules in [create-issue](../create-issue.md#rules). + +### 2. Raise It Against the Tracker + +- Create the issue on `{issue_platform}`, capturing its key and URL. + > - For GitHub, follow the [issue template](../../resources/github-issue-creation.md#issue-template) and [section rules](../../resources/github-issue-creation.md#section-rules), labelling the issue `chore`. + > - For Jira, obtain the Atlassian cloud ID via `getAccessibleAtlassianResources` before any other Jira call, and create the issue as a Task in the project the package's own issue lives in. + > - Where creation fails, leave the row's dash intact and report the failure with the row ID. A row is raised or it is not; a half-raised row would claim an issue that does not exist. + +### 3. Link the Row to Its Issue + +- Write the new issue's link into this row's Follow-up cell in place, leaving the ID, item and rationale columns as the deferring activity wrote them. The register is where a raised row is counted from, so the link in the cell is the whole record of the raise.