@mgiles/perk 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/extension/adapters/planAdapterPlannotator.ts +64 -1
- package/extension/doors/commitCompact.ts +163 -0
- package/extension/factories/gistAuthor.ts +94 -0
- package/extension/factories/gistDraft.ts +265 -0
- package/extension/factories/gistSave.ts +251 -0
- package/extension/factories/planMode.ts +8 -5
- package/extension/factories/planReview.ts +233 -12
- package/extension/index.ts +19 -0
- package/extension/substrate/git.ts +38 -0
- package/extension/substrate/toolGating.ts +8 -0
- package/extension/substrate/unifiedDiff.ts +224 -0
- package/package.json +2 -1
- package/prompts/_fixtures/live.yaml +13 -0
- package/prompts/commit-and-compact.md +7 -0
- package/prompts/contexts/adapters/plannotator-objective.md +8 -1
- package/prompts/contexts/adapters/plannotator-plan.md +6 -1
- package/prompts/contexts/gist-authoring.md +22 -0
- package/prompts/stages/gist-author/seed.md +10 -0
- package/prompts/stages/gist-save.md +9 -0
- package/shared/bindings.yaml +3 -0
- package/shared/contracts.md +119 -13
- package/shared/registry.yaml +31 -1
package/shared/contracts.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# perk cross-plane contracts
|
|
2
2
|
|
|
3
3
|
The language-neutral contracts both planes obey, authored once here and bundled into each
|
|
4
|
-
build artifact. This document holds the numbered **prose contract sections** (`§8.1`–`§8.
|
|
4
|
+
build artifact. This document holds the numbered **prose contract sections** (`§8.1`–`§8.41`,
|
|
5
5
|
non-contiguous: `§8.8` is skipped and `§8.6a` exists; no parser): the Python CLI (`perk`)
|
|
6
6
|
and the TS extension (`@mgiles/perk`) each implement one side, against the exact names/paths/
|
|
7
7
|
fields pinned in each section. `perk doctor` verifies conformance. The numbering convention:
|
|
@@ -386,7 +386,7 @@ swallowed**: a failed advance shows a visible `⚠ … NOT advanced — re-run /
|
|
|
386
386
|
**Tool gating.** The `mode` field **structurally gates tools** — enforcement, not prompting. When
|
|
387
387
|
`mode == "read-only"` the interior (`extension/substrate/toolGating.ts`): (1) restricts the
|
|
388
388
|
active tool set to `READ_ONLY_TOOLS` (`read`/`grep`/`find`/`ls`/`bash` + `ask_user_question` +
|
|
389
|
-
`plan_review` + the `plan_draft`/`objective_draft` session-data carve-outs + `objective_node`
|
|
389
|
+
`plan_review` + the `plan_draft`/`objective_draft`/`gist_draft` session-data carve-outs + `objective_node`
|
|
390
390
|
(delegates a bounded node transition to the canonical Python plane) + the **`web` seam**
|
|
391
391
|
providers' research tools, the read-only Linear tools, and the pi-subagents delegation family
|
|
392
392
|
(`subagent`/`wait` + the parent supervisor pair — the gated objective-plan explorer spawn must be
|
|
@@ -1169,11 +1169,12 @@ carries `base` from the `plan-header` so resume paths recover the pinned value.
|
|
|
1169
1169
|
|
|
1170
1170
|
**Label taxonomy (minimal):** `perk:plan` (green `1f883d`), `perk:learn` (purple `8250df`),
|
|
1171
1171
|
`perk:objective` (indigo `5319e7`, description "perk objective issue"), `perk:objective-node`
|
|
1172
|
-
(indigo `5319e7`, on Linear project-backed roadmap node-issues),
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1172
|
+
(indigo `5319e7`, on Linear project-backed roadmap node-issues), `perk:gist` (yellow `fbca04`,
|
|
1173
|
+
description "perk gist issue (a rough statement of intent)" — §8.41), and `perk:consolidated`
|
|
1174
|
+
(gray `6e7781`, description "perk learn issue consolidated into docs/learned"), each **lazily
|
|
1175
|
+
created** by its gateway create-op on first use. Query by a **single** label — GitHub label
|
|
1176
|
+
filters are AND-semantics. (On Linear, `perk init` / `doctor --fix` proactively ensure the six
|
|
1177
|
+
`perk:*` labels at **workspace** scope — §8.21.)
|
|
1177
1178
|
|
|
1178
1179
|
**The `pending-learn` semaphore.** An existence-only `cache.markers` file
|
|
1179
1180
|
(`.perk/workflow/markers/pending-learn`, name shared as `PENDING_LEARN` in both planes): **`land`
|
|
@@ -1317,7 +1318,7 @@ second `--fix` at `fixed == []`).
|
|
|
1317
1318
|
**Groups.** `environment` (tools; required tools missing = `fail`; optional tools (e.g. ast-grep)
|
|
1318
1319
|
missing = `warn`) · `github` (auth/access; non-fatal `warn`) ·
|
|
1319
1320
|
`linear` (verify-gated Linear readiness — auth/team/labels; present only when the committed
|
|
1320
|
-
`[issues] backend` is `"linear"`; warn-level, the github D3 mirror; `--fix` ensures the
|
|
1321
|
+
`[issues] backend` is `"linear"`; warn-level, the github D3 mirror; `--fix` ensures the six perk
|
|
1321
1322
|
labels — §8.21) · `runner` (remote-runner prereqs; report-only, non-fatal — §8.16) ·
|
|
1322
1323
|
`package` (settings wiring + perk-package ref reconcile + the `extension-install` install-ownership
|
|
1323
1324
|
check + the `required-perk-version` managed check over the committed `.perk/required-perk-version`
|
|
@@ -1528,6 +1529,7 @@ perk's workflow skills are prompt-hidden; `transclude` exists for the user-bindi
|
|
|
1528
1529
|
| trigger | skill | mode |
|
|
1529
1530
|
|---|---|---|
|
|
1530
1531
|
| `stage:plan` | `perk-plan` | `nudge` |
|
|
1532
|
+
| `stage:gist-author` | `perk-gist-author` | `nudge` |
|
|
1531
1533
|
| `stage:objective-author` | `perk-objective-author` | `nudge` |
|
|
1532
1534
|
| `stage:objective-plan` | `perk-objective-plan` | `nudge` |
|
|
1533
1535
|
| `stage:implement` | `perk-implement` | `nudge` |
|
|
@@ -3009,8 +3011,9 @@ init/doctor probe — report-shaped, never raises; phases short-circuit auth →
|
|
|
3009
3011
|
remediation "export LINEAR_API_KEY (create a personal API key at linear.app Settings →
|
|
3010
3012
|
Security & access), or set [linear] api_key in .perk/local.toml".
|
|
3011
3013
|
- `linear-team` — ok: `team <key> found`; failure: warn with the error detail.
|
|
3012
|
-
- `linear-labels` — all
|
|
3013
|
-
`perk:objective`, `perk:objective-node`): ok; otherwise warn listing the missing
|
|
3014
|
+
- `linear-labels` — all six perk labels present (`perk:plan`, `perk:learn`, `perk:consolidated`,
|
|
3015
|
+
`perk:objective`, `perk:objective-node`, `perk:gist`): ok; otherwise warn listing the missing
|
|
3016
|
+
names,
|
|
3014
3017
|
remediation "run `perk init` or `perk doctor --fix`". perk's labels are created
|
|
3015
3018
|
**workspace-scoped** (no `teamId` on create — Linear's cross-team-label guidance; the lookup is
|
|
3016
3019
|
unscoped, so a pre-existing team-scoped label still counts).
|
|
@@ -3031,14 +3034,14 @@ safely auto-create them).
|
|
|
3031
3034
|
|
|
3032
3035
|
**The `--fix` label repair gesture** (`_fix_linear_labels`, verify-gated like the skills sync —
|
|
3033
3036
|
network I/O, so never a `ManagedConvergence`): when `fix` AND `verify` AND linear is selected AND
|
|
3034
|
-
key + team are available, `check_readiness(..., ensure_labels=True)` ensures the
|
|
3037
|
+
key + team are available, `check_readiness(..., ensure_labels=True)` ensures the six labels;
|
|
3035
3038
|
created names land on `fixed` (`Linear: created label perk:plan`), failures on `fix_errors`.
|
|
3036
3039
|
Lookup-first idempotency: a converged workspace reports nothing (the doctor idempotency rule).
|
|
3037
3040
|
|
|
3038
3041
|
**The init readiness step** (`perk/convergence/init/__init__.py::_linear_readiness`, verify-gated, non-fatal — the
|
|
3039
3042
|
GitHub D3 mirror: file convergence already succeeded). Only when `verify` AND the committed
|
|
3040
3043
|
backend is `"linear"`: missing key/team degrade to an errored `LinearReport`; otherwise the probe
|
|
3041
|
-
runs with `ensure_labels=True` (init converges the
|
|
3044
|
+
runs with `ensure_labels=True` (init converges the six perk labels upfront; the lazy write-time
|
|
3042
3045
|
`ensure_label` calls remain the safety net). Created labels are reported through the
|
|
3043
3046
|
`LinearReport` (the `--json` `linear` key, §8.5; the human `✓ Linear: <user>, team <key>` line) —
|
|
3044
3047
|
**never** appended to `InitReport.changes`, which stays a pure filesystem-delta list.
|
|
@@ -3213,6 +3216,34 @@ one-stop current shape.
|
|
|
3213
3216
|
| `plannotator-plan` | `PLAN_ADAPTER_PLANNOTATOR_CONTEXT` | browser bridge | present + `/plan-save` |
|
|
3214
3217
|
| `tombell-plan` | `PLAN_ADAPTER_TOMBELL_CONTEXT` (conditioned injection, Node 2.6) | first-party in-TUI review | present + `/plan-save` (incl. tombell's own interactive `/plan` `setActiveTools` restriction arm) |
|
|
3215
3218
|
|
|
3219
|
+
- **Plannotator "Direct Edits" (browser edits of the reviewed document).** Plannotator's
|
|
3220
|
+
plan-review browser lets the reviewer edit the reviewed document directly; the edits arrive as
|
|
3221
|
+
PROSE inside the existing `feedback` string, never a new envelope field — a `# Direct Edits`
|
|
3222
|
+
section (heading + preamble + a ```` ```diff ```` fence containing a jsdiff
|
|
3223
|
+
`createTwoFilesPatch(…, { context: 3 })` patch, `trimEnd()`'d, against the exact bytes perk
|
|
3224
|
+
submitted), composed FIRST, with non-sentinel annotation feedback following after
|
|
3225
|
+
`\n\n---\n\n` (format pin: plannotator `packages/editor/directEdits.ts`
|
|
3226
|
+
`buildDirectEditsSection`/`composeFeedbackWithDirectEdits` @ v0.26.1 — prose, not a pinned
|
|
3227
|
+
API). perk handles it asymmetrically per arm:
|
|
3228
|
+
- **Plan arm, APPROVE:** mechanical apply — strict extraction (`extractDirectEdits`,
|
|
3229
|
+
`extension/adapters/planAdapterPlannotator.ts`) → strict clean-apply (`applyUnifiedDiff`,
|
|
3230
|
+
`extension/substrate/unifiedDiff.ts`, a vendored zero-runtime-dep applier; null on any
|
|
3231
|
+
anomaly) → `writePlanDraft` write-back (reviewed bytes == artifact bytes == saved bytes) →
|
|
3232
|
+
save the EDITED bytes with `details.edited: true` and the annotation remainder as the only
|
|
3233
|
+
surviving feedback. The **fail-open ladder**: no section → today's path byte-stable; a
|
|
3234
|
+
heading that cannot be parsed / applied / written back → the verbatim save plus a loud
|
|
3235
|
+
warning in the approved text and `details.direct_edits_applied: false` (the diff stays in
|
|
3236
|
+
the surfaced feedback for a manual follow-up). Worst-case upstream format drift degrades to
|
|
3237
|
+
exactly the pre-Direct-Edits behavior.
|
|
3238
|
+
- **Objective arm, APPROVE with a Direct Edits section:** NO save — the save seam re-reads the
|
|
3239
|
+
STRUCTURED draft, so rendered-markdown edits (roadmap-table rows included) cannot be folded
|
|
3240
|
+
back mechanically. The arm returns a NON-terminating revise round (`details.status:
|
|
3241
|
+
"revise"`, `reason: "direct_edits"`, gate untouched): the model folds the diff into
|
|
3242
|
+
`objective_draft`, then calls `plan_review` again to confirm. perk never saves an objective
|
|
3243
|
+
the reviewer explicitly edited away from.
|
|
3244
|
+
- **DENY (both arms):** model-mediated — the feedback (diff included) passes through verbatim
|
|
3245
|
+
for the `plan_draft`/`objective_draft` rewrite.
|
|
3246
|
+
|
|
3216
3247
|
- **Link/`consumed_learn` recovery carriers.** Approval-triggered saves carry **no model params**;
|
|
3217
3248
|
the **cold** `handoff_extra` carrier (→ §8.2) and the **warm** `objective_node_claim` carrier
|
|
3218
3249
|
(→ §8.3) recover `objective_id`/`node_id` with identical semantics — fill both-or-neither,
|
|
@@ -4815,7 +4846,9 @@ stage (a forked implement session is an implement session); **adopt never impers
|
|
|
4815
4846
|
subagent children stay unscoped — their fresh branch carries no stage). Stage-borrowing cold
|
|
4816
4847
|
doors land on real stage ids (`plan from`/`plan replan`/`learn docs`/`learn code` borrow `plan`;
|
|
4817
4848
|
`objective replan`/`objective author --from` borrow `objective-author`; `skills create/refine`
|
|
4818
|
-
borrow `save`), so the per-stage sets cover every borrower.
|
|
4849
|
+
borrow `save`), so the per-stage sets cover every borrower. The gist stages (`gist-author`,
|
|
4850
|
+
`gist-save` — §8.41) each carry `ask_user_question` + `gist_draft` + `gist_save` + the research
|
|
4851
|
+
families (the objective-author shape; `plan_review` governs via the gate-ON set). **Scoped universe:
|
|
4819
4852
|
`PERK_TOOLS ∪ BORROWED_TOOLS`** — perk's own name-keyed census plus the enumerated
|
|
4820
4853
|
borrowed-package census (the web-provider union, pi-mono-linear's 25 tools, pi-subagents'
|
|
4821
4854
|
delegation four, `todo`, `plannotator_submit_plan`); builtins and un-enumerated foreign names
|
|
@@ -4870,3 +4903,76 @@ lever the gate's allowlist uses; `edit`/`write`/`bash` blocking remains the gate
|
|
|
4870
4903
|
config surface for the map (the §8.39 non-interference posture; fail-open on unknown ids covers
|
|
4871
4904
|
version skew). **Bare-session zero-change guarantee:** a session that never engages either
|
|
4872
4905
|
concern gets **zero `setActiveTools` calls** — bare warm sessions stay byte-identical.
|
|
4906
|
+
|
|
4907
|
+
## §8.41 · The gist tier (lightweight statements of intent)
|
|
4908
|
+
|
|
4909
|
+
A **gist** is a backend-tracked **statement of intent** — a rough, thematically
|
|
4910
|
+
problem-space-focused note of "something we would likely want to do", upstream of both plans and
|
|
4911
|
+
objectives. It is **code-informed but carries no implementation strategy** (no steps, no roadmap,
|
|
4912
|
+
no estimates); the lightness lives in the ARTIFACT and the skill guidance, not the machinery. A
|
|
4913
|
+
gist's **scope** (`plan` | `objective`) records its intended consumption tier: a storage
|
|
4914
|
+
discriminator on Linear (issue vs project), a header hint on GitHub.
|
|
4915
|
+
|
|
4916
|
+
**Registry topology (settled decision).** The two gist stages (`gist-author` → `gist-save`) form
|
|
4917
|
+
a **separate, disconnected component** — no edges into the main loop. Gists are optional; nothing
|
|
4918
|
+
routes off "which stage is initial" except the validator, which requires **at least one** initial
|
|
4919
|
+
stage (zero initials — a pure cycle — stays an error). Consumption happens via the unchanged
|
|
4920
|
+
§8.29/§8.30 in-place adoption doors (`perk plan from <gist>` /
|
|
4921
|
+
`perk objective author --from <gist>`), never via stage edges: a gist is consumable because it is
|
|
4922
|
+
an ordinary OPEN backend object without plan/objective metadata.
|
|
4923
|
+
|
|
4924
|
+
**Metadata.** The `perk:gist` label (yellow `fbca04`, description "perk gist issue (a rough
|
|
4925
|
+
statement of intent)"), lazily created by its create-op on first use — the sixth `perk:*` label.
|
|
4926
|
+
The `gist-header` metadata block carries `run_id`, `created`, and `scope` (`plan` | `objective`;
|
|
4927
|
+
lenient read — an unknown stored scope parses to `None`). Per-backend storage:
|
|
4928
|
+
|
|
4929
|
+
- **GitHub** — an issue: the html-style `gist-header` block rendered into the body above the
|
|
4930
|
+
prose.
|
|
4931
|
+
- **Linear, scope `plan`** — an issue: clean transcoded prose body + a `gist-header` **native
|
|
4932
|
+
attachment** (kind `gist-header`, URL `https://perk.invalid/gist/<run_id>`, title
|
|
4933
|
+
"Perk gist", subtitle = scope; the §8.24 attachment-metadata posture).
|
|
4934
|
+
- **Linear, scope `objective`** — a **project**: the overview carries an inline-code
|
|
4935
|
+
`gist-header` block above the transcoded prose. No milestones, no node-issues, no metadata
|
|
4936
|
+
sentinel — deliberately light; the overview block IS the identity (projects have no
|
|
4937
|
+
attachments).
|
|
4938
|
+
|
|
4939
|
+
**The `IssueBackend` gist trio** (docstring contracts mirroring the learn trio):
|
|
4940
|
+
`find_gist_issue{run_id}` (label + header-key scoped — cannot return a plan/learn issue),
|
|
4941
|
+
`create_gist_issue{title, body, run_id, scope, dry_run}` (idempotent via the finder; stamps
|
|
4942
|
+
`scope` into the header), and `list_gist_issues{} -> GistSummary[]{id, title, url, body, scope,
|
|
4943
|
+
adopted}` — every OPEN `perk:gist` issue; raises on infra failure, never masks as empty. The
|
|
4944
|
+
`ObjectiveStore` grows the project-tier pair in the no-op-return family:
|
|
4945
|
+
`create_gist_source{title, prose, run_id, dry_run} -> ObjectiveRef | None` (`None` = "no project
|
|
4946
|
+
surface" — the CLI falls back to the issue tier; the Linear project store creates/finds the gist
|
|
4947
|
+
project) and `list_gist_sources{} -> GistSummary[]` (`()` outside the project store).
|
|
4948
|
+
|
|
4949
|
+
**Adopted detection.** A gist whose stored metadata ALSO carries the adopting tier's metadata
|
|
4950
|
+
(distinct keys — adoption stamps additively beside the `gist-header`, no collision) is
|
|
4951
|
+
**adopted**: on GitHub the `plan-header`/`objective-header` block joins the body; on a Linear
|
|
4952
|
+
issue the signal is a `plan-header` attachment; on a Linear project it is the **Reconcilable
|
|
4953
|
+
region** the adoption composer writes into the overview (the objective headers ride the
|
|
4954
|
+
sentinel's attachments, never an overview block; the original gist overview — with its
|
|
4955
|
+
`gist-header` — survives verbatim in the Immutable archive note, keeping the project scannable
|
|
4956
|
+
as a gist). `perk gist list` default **hides** adopted gists (the "what's still unconsumed" backlog
|
|
4957
|
+
view); `--all` shows everything with an adopted marker. No gist-specific consumption
|
|
4958
|
+
bookkeeping: in-place adoption means the gist *becomes* the plan/objective and inherits its
|
|
4959
|
+
lifecycle.
|
|
4960
|
+
|
|
4961
|
+
**The save worker (`perk gist create --json`).** Options `--body <path>` (required), `--title`,
|
|
4962
|
+
`--scope [plan|objective]`, `--run-id`, `--dry-run`. Scope resolution: explicit `--scope` > the
|
|
4963
|
+
`gist_scope` **handoff** key (a declared `Handoff` field, stashed by `perk gist author --scope`
|
|
4964
|
+
— the `adopt_from` handoff pattern; best-effort recovery, never blocks a save) > `"plan"`. Scope
|
|
4965
|
+
`objective` routes to `ObjectiveStore.create_gist_source` first, falling back to the issue tier
|
|
4966
|
+
on a `None` return; scope `plan` goes to the issue backend directly. Envelope:
|
|
4967
|
+
`{"success": true, "error_type": null, "gist": {"id", "url", "existed"}, "scope", "dry_run"}` —
|
|
4968
|
+
opaque string ids (§8.21). Human output prints the created/found line plus a consumption hint
|
|
4969
|
+
(`perk plan from <id>` / `perk objective author --from <id>`).
|
|
4970
|
+
|
|
4971
|
+
**The warm flow** is the full review-first mirror of plan/objective authoring: the `gist_draft`
|
|
4972
|
+
tool (the third draft-file tool — §8.1's carve-out family; artifact `gist-draft.json`, shape
|
|
4973
|
+
`{schema_version: 1, title?, scope?, prose}`) keeps the draft current; `plan_review` in a
|
|
4974
|
+
`gist-author` session reviews the **rendered markdown** (title + scope line + prose — never raw
|
|
4975
|
+
JSON), VIEW-ONLY first-party (the objective-arm shape; deny+feedback is the change channel);
|
|
4976
|
+
APPROVED auto-saves via `gistApprovalSave` → the `gist_save` tool / `perk gist create`;
|
|
4977
|
+
`/gist-save` is the manual failsafe. No draft → soft-skip `reason: "no_gist_draft"`. No session
|
|
4978
|
+
linkage after save — nothing consumes a gist in-session.
|
package/shared/registry.yaml
CHANGED
|
@@ -27,6 +27,7 @@ state_keys:
|
|
|
27
27
|
- comments # discussion comments
|
|
28
28
|
- review-threads # review threads (distinct API from comments)
|
|
29
29
|
- learn # the perk:learn knowledge-capture issue (P2.T8b)
|
|
30
|
+
- gist # the perk:gist statement-of-intent issue (contracts.md §8.41)
|
|
30
31
|
# Tier 2 · .perk/workflow/ — the local cache (see contracts.md §8.1).
|
|
31
32
|
cache:
|
|
32
33
|
- plan # materialized plan body cache
|
|
@@ -41,7 +42,10 @@ state_keys:
|
|
|
41
42
|
|
|
42
43
|
# ---------------------------------------------------------------------------
|
|
43
44
|
# Stages — the loop (Q5): objective-author -> objective-save -> objective-plan -> plan ->
|
|
44
|
-
# save -> implement -> submit -> address -> land -> learn
|
|
45
|
+
# save -> implement -> submit -> address -> land -> learn — plus the OPTIONAL gist
|
|
46
|
+
# component (gist-author -> gist-save), deliberately disconnected from the loop:
|
|
47
|
+
# a saved gist is consumed by the in-place adoption doors (`perk plan from`,
|
|
48
|
+
# `perk objective author --from`), not by stage edges (contracts.md §8.41).
|
|
45
49
|
#
|
|
46
50
|
# Every field is locked EXCEPT `requires`/`reads`/`writes` (empty until handlers
|
|
47
51
|
# land). `run_id` is uniform AND shape-locked by the validator: `perk/substrate/registry.py`
|
|
@@ -59,6 +63,32 @@ state_keys:
|
|
|
59
63
|
# local-only by design — review, merge, and judgment capture stay where a human is.
|
|
60
64
|
# ---------------------------------------------------------------------------
|
|
61
65
|
stages:
|
|
66
|
+
- id: gist-author
|
|
67
|
+
summary: Draft a gist — a rough statement of intent (read-only authoring).
|
|
68
|
+
mode: read-only
|
|
69
|
+
worktree: none # interactive authoring, like plan — no branch, no gist yet
|
|
70
|
+
doors: { warm: true, cold_local: true, cold_remote: false } # interactive local authoring
|
|
71
|
+
run_id: { warm: keep, cold_local: mint, cold_remote: mint }
|
|
72
|
+
command: gist author # dedicated seeded cold door (perk gist author)
|
|
73
|
+
requires: [] # nothing exists yet — this stage CREATES the gist
|
|
74
|
+
reads: []
|
|
75
|
+
writes: [session.workflow-state, cache.session-data] # the read-only `mode` append; gist_draft writes the gist-draft artifact + its session_artifacts pointer
|
|
76
|
+
predecessors: [] # an initial of the disconnected gist component
|
|
77
|
+
successors: [gist-save]
|
|
78
|
+
|
|
79
|
+
- id: gist-save
|
|
80
|
+
summary: Persist the drafted gist to the issue backend; the read-only -> read-write boundary.
|
|
81
|
+
mode: read-write
|
|
82
|
+
worktree: none # still no branch; save writes the gist issue/project
|
|
83
|
+
doors: { warm: true, cold_local: true, cold_remote: false }
|
|
84
|
+
run_id: { warm: keep, cold_local: mint, cold_remote: mint }
|
|
85
|
+
command: gist save # the gist_save terminating tool + /gist-save command
|
|
86
|
+
requires: []
|
|
87
|
+
reads: []
|
|
88
|
+
writes: [github.gist, session.workflow-state] # create the gist issue/project
|
|
89
|
+
predecessors: [gist-author]
|
|
90
|
+
successors: [] # a terminal — consumption happens via the adoption doors, not edges
|
|
91
|
+
|
|
62
92
|
- id: objective-author
|
|
63
93
|
summary: Draft a new objective + roadmap (read-only authoring).
|
|
64
94
|
mode: read-only
|