ecoportal-api-graphql 1.3.10 → 1.3.12
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.
- checksums.yaml +4 -4
- data/.ai-assistance/code/diff_pairing_engine.md +243 -0
- data/.ai-assistance/code/filter_contract_matrix.md +177 -0
- data/.ai-assistance/code/graphql_domain_knowledge.md +20 -10
- data/.ai-assistance/code/template_diff_pairing_domain.md +175 -0
- data/.ai-assistance/code/workflow-command-guide.md +28 -0
- data/.ai-assistance/projects/ooze-graphql-native-migration/INVENTORY.md +136 -0
- data/.ai-assistance/projects/ooze-graphql-native-migration/TODO.md +6 -1
- data/.ai-assistance/projects/qa-services-delivery/DECISIONS.md +93 -0
- data/.ai-assistance/projects/qa-services-delivery/INTENT.md +76 -0
- data/.ai-assistance/projects/qa-services-delivery/PHASE3-SCOPE.md +115 -0
- data/.ai-assistance/projects/qa-services-delivery/ROADMAP.md +99 -0
- data/.ai-assistance/projects/qa-services-delivery/TODO.md +81 -0
- data/.ai-assistance/projects/template-automatic-build-maintenance/INTENT.md +87 -0
- data/.ai-assistance/projects/template-automatic-build-maintenance/TODO.md +108 -0
- data/.ai-assistance/projects/template-diff-deploy/INTENT.md +12 -0
- data/.ai-assistance/projects/template-diff-deploy/TODO.md +9 -0
- data/.ai-assistance/projects/template-maintenance/PHASE0-FINDINGS.md +93 -0
- data/.ai-assistance/projects/template-maintenance/README.md +14 -0
- data/.ai-assistance/skills/procedural-memory/SKILL.md +319 -0
- data/.ai-assistance/standards-version.json +21 -20
- data/CHANGELOG.md +119 -0
- data/CLAUDE.md +10 -0
- data/docs/self-docs/ARCHITECTURE.md +88 -0
- data/docs/self-docs/CHANGES.jsonl +7 -0
- data/docs/self-docs/CONVENTIONS.md +74 -0
- data/docs/self-docs/INTEGRATIONS.md +63 -0
- data/docs/self-docs/OVERVIEW.md +51 -0
- data/docs/self-docs/STATUS.md +69 -0
- data/docs/self-docs/self-docs-index.json +39 -0
- data/docs/worklog.md +256 -0
- data/ecoportal-api-graphql.gemspec +1 -1
- data/lib/ecoportal/api/common/graphql/model/diffable.rb +54 -54
- data/lib/ecoportal/api/graphql/base/action.rb +43 -43
- data/lib/ecoportal/api/graphql/base/contractor_entity/member_changes.rb +67 -67
- data/lib/ecoportal/api/graphql/base/page/data_field/collection.rb +7 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/contractor_entities.rb +28 -28
- data/lib/ecoportal/api/graphql/base/page/data_field/file_field.rb +25 -25
- data/lib/ecoportal/api/graphql/base/page/data_field/image_gallery.rb +24 -24
- data/lib/ecoportal/api/graphql/base/page/data_field.rb +1 -1
- data/lib/ecoportal/api/graphql/base/page/section_collection.rb +85 -79
- data/lib/ecoportal/api/graphql/base/preset_view.rb +17 -17
- data/lib/ecoportal/api/graphql/base/register.rb +18 -18
- data/lib/ecoportal/api/graphql/builder/template_builder.rb +174 -0
- data/lib/ecoportal/api/graphql/builder.rb +17 -16
- data/lib/ecoportal/api/graphql/compat/filter_translator.rb +63 -28
- data/lib/ecoportal/api/graphql/concerns/page_compat.rb +51 -51
- data/lib/ecoportal/api/graphql/concerns.rb +14 -14
- data/lib/ecoportal/api/graphql/diff/change.rb +59 -0
- data/lib/ecoportal/api/graphql/diff/command_synthesizer.rb +329 -0
- data/lib/ecoportal/api/graphql/diff/cross_object_diff.rb +165 -0
- data/lib/ecoportal/api/graphql/diff/deploy.rb +121 -0
- data/lib/ecoportal/api/graphql/diff/id_resolver.rb +64 -0
- data/lib/ecoportal/api/graphql/diff/pairing/candidate.rb +32 -0
- data/lib/ecoportal/api/graphql/diff/pairing/engine.rb +173 -0
- data/lib/ecoportal/api/graphql/diff/pairing/ledger.rb +119 -0
- data/lib/ecoportal/api/graphql/diff/pairing/signals.rb +104 -0
- data/lib/ecoportal/api/graphql/diff/strategy.rb +113 -0
- data/lib/ecoportal/api/graphql/diff/version_diff.rb +332 -0
- data/lib/ecoportal/api/graphql/diff.rb +34 -0
- data/lib/ecoportal/api/graphql/file_upload/client.rb +181 -181
- data/lib/ecoportal/api/graphql/fragment/page.rb +85 -85
- data/lib/ecoportal/api/graphql/fragment/pages/common_page_union.rb +1 -0
- data/lib/ecoportal/api/graphql/input/action/update.rb +14 -14
- data/lib/ecoportal/api/graphql/input/contractor_entity/update.rb +41 -41
- data/lib/ecoportal/api/graphql/input/location_structure/apply_commands.rb +47 -47
- data/lib/ecoportal/api/graphql/input/location_structure/draft/add_commands.rb +49 -49
- data/lib/ecoportal/api/graphql/input/location_structure/update_command.rb +27 -27
- data/lib/ecoportal/api/graphql/input/search_conf.rb +436 -367
- data/lib/ecoportal/api/graphql/input/workflow_command/add_field.rb +27 -18
- data/lib/ecoportal/api/graphql/interface/location_structure/command.rb +30 -30
- data/lib/ecoportal/api/graphql/logic/input.rb +26 -26
- data/lib/ecoportal/api/graphql/mutation/action/archive.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/action/create.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/action/update.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/contractor_entity/create.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/contractor_entity/destroy.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/contractor_entity/update.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/kickstand/fail_workflow.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/kickstand/start_workflow.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/kickstand/stop_workflow.rb +1 -1
- data/lib/ecoportal/api/graphql.rb +1 -0
- data/lib/ecoportal/api/graphql_version.rb +1 -1
- data/tests/dump_template_model.rb +90 -0
- data/tests/validate_queries.rb +31 -9
- metadata +40 -3
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: procedural-memory
|
|
3
|
+
category: governance
|
|
4
|
+
version: 0.2.0
|
|
5
|
+
status: draft
|
|
6
|
+
description: >
|
|
7
|
+
Distills accumulated session signals into stored `procedural` memory entries
|
|
8
|
+
(recurring routines: a trigger condition + the action that reliably follows) and
|
|
9
|
+
surfaces them as likely next steps. Invoke on a periodic distill pass or when a
|
|
10
|
+
developer asks what patterns you have noticed in how they work.
|
|
11
|
+
triggers:
|
|
12
|
+
- what patterns have you noticed
|
|
13
|
+
- distill my routines
|
|
14
|
+
- procedural memory
|
|
15
|
+
- how do I work
|
|
16
|
+
- learn my routines
|
|
17
|
+
- weekly distill
|
|
18
|
+
- modus operandi
|
|
19
|
+
applicable_to:
|
|
20
|
+
- any
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# procedural-memory
|
|
24
|
+
|
|
25
|
+
## Purpose
|
|
26
|
+
|
|
27
|
+
Turn the substrate of accumulated session history into stored **`procedural`** memory --
|
|
28
|
+
recurring routines, each expressed as a **trigger condition** and the **inferred action**
|
|
29
|
+
that reliably follows it -- and surface those routines (plus a short "likely next steps"
|
|
30
|
+
list) so the next session starts proactively shaped instead of from scratch.
|
|
31
|
+
|
|
32
|
+
This skill operationalizes the **Distill** stage of the Observe -> Distill -> Act loop, plus
|
|
33
|
+
the human-facing part of the **Act** stage (surfacing). It implements
|
|
34
|
+
`standards/workflows/procedural-memory.md`. Observation (the `Stop`/`SessionEnd` logging
|
|
35
|
+
substrate) and autonomous execution (the auto-worker) are out of scope here -- this skill
|
|
36
|
+
reads the Observe substrate and writes the inferred routines; it never acts on them itself.
|
|
37
|
+
|
|
38
|
+
> **v0.2.0 -- draft-aligned, blockers resolved.** This skill tracks
|
|
39
|
+
> `standards/workflows/procedural-memory.md` at v0.2.0 (`status: draft`, ready for consolidation
|
|
40
|
+
> review). It implements the now-decided **decay/retirement lifecycle** (D1) and **Observe-stage
|
|
41
|
+
> privacy policy** (D2). The distill cadence, the minimum-observation threshold, the promotion
|
|
42
|
+
> rule, and the lifecycle numbers (confidence steps, retirement floor, staleness/cool-off
|
|
43
|
+
> windows) are all **provisional** and will firm up when the standard reaches `status: reviewed`.
|
|
44
|
+
> Treat the numbers below as conservative defaults, not settled policy.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## When to invoke
|
|
49
|
+
|
|
50
|
+
- **On a periodic distill pass** -- e.g. weekly, or as part of an end-of-week wrap-up. This is
|
|
51
|
+
the primary mode: a scheduled mining pass over accumulated session history.
|
|
52
|
+
- **On demand** -- when a developer asks "what patterns have you noticed in how I work?",
|
|
53
|
+
"distill my routines", or similar. Run the same procedure, scoped to the data available.
|
|
54
|
+
|
|
55
|
+
Do not invoke this skill to *perform* a routine -- it only distils and surfaces. Acting on a
|
|
56
|
+
surfaced routine is gated separately (see HARD CONSTRAINTS).
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## On invocation
|
|
61
|
+
|
|
62
|
+
Before any other output, do both of the following:
|
|
63
|
+
|
|
64
|
+
1. Print to the user:
|
|
65
|
+
`[skill: procedural-memory] <one-line description of what you are about to do>`
|
|
66
|
+
Examples:
|
|
67
|
+
- Periodic pass: `[skill: procedural-memory] weekly distill — mining usage log for recurring routines`
|
|
68
|
+
- On demand: `[skill: procedural-memory] reviewing session history for patterns in how you work`
|
|
69
|
+
|
|
70
|
+
2. Append a usage record to `.ai-assistance/local/kpi/usage-<YYYY-WNN>.jsonl`
|
|
71
|
+
(ISO week format, e.g. `2026-W26`):
|
|
72
|
+
```json
|
|
73
|
+
{"component": "skill/procedural-memory", "action": "invoked", "detail": "<same one-liner>", "ts": "<ISO timestamp>", "session_id": "<if known>"}
|
|
74
|
+
```
|
|
75
|
+
Before writing, run the scrub/redaction pass (see Privacy below) over the record. If the file
|
|
76
|
+
or directory does not exist, create it. If writing fails, continue silently.
|
|
77
|
+
|
|
78
|
+
### Consent check (do this first)
|
|
79
|
+
|
|
80
|
+
The Observe log is **opt-in**. Before reading any `usage-*.jsonl` to mine routines, confirm the
|
|
81
|
+
developer has enabled Observe (`procedural_memory.observe: true` in local settings, or the
|
|
82
|
+
equivalent Observe-hook entry). If consent is not set, report that the Observe stage is not
|
|
83
|
+
enabled, do NOT read the log, and stop. (Writing this skill's own invoked/completed usage
|
|
84
|
+
records is the skill announcing itself and is unaffected by the Observe consent flag.)
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## The procedure
|
|
89
|
+
|
|
90
|
+
### Step 1 -- Read the Observe substrate
|
|
91
|
+
|
|
92
|
+
The Observe stage is append-only and machine-local; this skill only reads it. Read only after
|
|
93
|
+
the consent check above has passed.
|
|
94
|
+
|
|
95
|
+
- Read `.ai-assistance/local/kpi/usage-<YYYY-WNN>.jsonl` across the distill window (default: the
|
|
96
|
+
current and previous 3 ISO weeks). These records carry only low-sensitivity signal: command/
|
|
97
|
+
tool names (not arguments), file paths/types touched, components invoked, event types and
|
|
98
|
+
`action` values, and coarse durations/counts -- never full arguments, file contents, or
|
|
99
|
+
prompt/response text (see Privacy below). Parse defensively: skip malformed/corrupt JSON lines
|
|
100
|
+
rather than failing the whole pass.
|
|
101
|
+
- Optionally read `docs/worklog.md` for `<!-- LEARNING: ... -->` markers. These are the
|
|
102
|
+
human-authored analogue of a `procedural` entry and may seed the distill pass
|
|
103
|
+
(`standards/workflows/session-handoff.md`).
|
|
104
|
+
|
|
105
|
+
If no usage log exists, report that the Observe substrate is not yet populated and stop --
|
|
106
|
+
there is nothing to distil. Do not invent routines from a single session.
|
|
107
|
+
|
|
108
|
+
### Step 2 -- Mine for recurring patterns
|
|
109
|
+
|
|
110
|
+
A pattern is a **trigger condition** plus the **action that reliably follows it** within the
|
|
111
|
+
same or the next session. Look for:
|
|
112
|
+
|
|
113
|
+
- An action that consistently follows a specific event (e.g. a code-spec regeneration that
|
|
114
|
+
follows every merge to `main`).
|
|
115
|
+
- A consistent ordering of actions (e.g. tests -> lint -> commit).
|
|
116
|
+
- A deferral that is consistently picked up at a predictable later point.
|
|
117
|
+
|
|
118
|
+
**Minimum-observation threshold.** A pattern is only written if it was **observed in >= 3
|
|
119
|
+
distinct sessions** in the window. This default is deliberately conservative to stop a one-off
|
|
120
|
+
coincidence becoming a stored routine; the standard leaves the exact number open, so treat
|
|
121
|
+
this as **provisional**. Below threshold: note it as a *candidate* in the report, but do not
|
|
122
|
+
write a memory entry.
|
|
123
|
+
|
|
124
|
+
### Step 3 -- Write each confirmed pattern as a `procedural` memory entry
|
|
125
|
+
|
|
126
|
+
Write each pattern at or above threshold into the repo-scoped memory directory
|
|
127
|
+
`~/.claude/projects/<project>/memory/` (auto memory -- repo-scoped and machine-local), as a
|
|
128
|
+
memory entry of **type `procedural`**. The body carries **Trigger:** and **Inferred action:**
|
|
129
|
+
lines, mirroring how `feedback` entries use **Why:** / **How to apply:**:
|
|
130
|
+
|
|
131
|
+
```markdown
|
|
132
|
+
## [Short routine name]
|
|
133
|
+
|
|
134
|
+
**Trigger:** [the observed condition that recurs]
|
|
135
|
+
**Inferred action:** [what the developer reliably does next]
|
|
136
|
+
**Confidence:** 0.6
|
|
137
|
+
**First-observed:** [YYYY-MM-DD]
|
|
138
|
+
**Last-observed:** [YYYY-MM-DD]
|
|
139
|
+
|
|
140
|
+
Observed in X of Y opportunities across N sessions (source: usage-<YYYY-WNN> ... usage-<YYYY-WNN>).
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
New entries start at **Confidence: 0.6** (provisional) -- above the retirement floor, below full
|
|
144
|
+
trust, so a freshly inferred routine starts on probation. **First-observed** and **Last-observed**
|
|
145
|
+
are both set to the current distill-pass date on first write. These three lines are required: they
|
|
146
|
+
drive the decay/retirement lifecycle in Step 3b.
|
|
147
|
+
|
|
148
|
+
Then add the index pointer line to `~/.claude/projects/<project>/memory/MEMORY.md`, matching
|
|
149
|
+
the existing index style:
|
|
150
|
+
|
|
151
|
+
```markdown
|
|
152
|
+
- [Procedural: <short routine name>](<filename>.md) — <one-line trigger → action summary>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Mark the entry clearly as `procedural` so it stays distinguishable from `user`/`project`
|
|
156
|
+
memory (see HARD CONSTRAINTS).
|
|
157
|
+
|
|
158
|
+
### Step 3b -- Re-evaluate, decay, and retire existing routines
|
|
159
|
+
|
|
160
|
+
On every distill pass, before reporting, walk each existing `procedural` entry and update its
|
|
161
|
+
lifecycle metadata (standard D1). Honour forced markers first, then apply the arithmetic.
|
|
162
|
+
|
|
163
|
+
1. **Forced markers (one-shot, applied first).** Scan `docs/worklog.md` and the memory files for:
|
|
164
|
+
- `<!-- RETIRE: <short routine name> -->` -- retire that routine immediately (see step 4
|
|
165
|
+
below), regardless of confidence or recency.
|
|
166
|
+
- `<!-- CONFIRM: <short routine name> -->` -- set its **Confidence** to `1.0` and refresh
|
|
167
|
+
**Last-observed** to today.
|
|
168
|
+
Record that the marker was applied so it is not re-applied on the next pass.
|
|
169
|
+
|
|
170
|
+
2. **Re-evaluate against this window.** For each routine whose **Trigger** occurred at least once
|
|
171
|
+
in the window:
|
|
172
|
+
- trigger fired AND inferred action followed: refresh **Last-observed** to today and
|
|
173
|
+
**increment Confidence by +0.1**, capped at `1.0`;
|
|
174
|
+
- trigger fired but action did NOT follow: **decrement Confidence by -0.2** (contradiction
|
|
175
|
+
costs more than a single confirmation earns -- intentional asymmetry);
|
|
176
|
+
- trigger did not fire at all: leave Confidence unchanged; do NOT refresh Last-observed.
|
|
177
|
+
|
|
178
|
+
3. **Retire** a routine when EITHER its **Confidence < 0.3** (floor) OR its **Last-observed** is
|
|
179
|
+
**older than 90 days** (staleness window). All thresholds provisional.
|
|
180
|
+
|
|
181
|
+
4. **Archive on retirement -- never silent-delete.** Move the entry file to
|
|
182
|
+
`~/.claude/projects/<project>/memory/retired/`, appending the retirement date and reason
|
|
183
|
+
(`confidence floor` / `staleness` / `forced`). Remove its line from `MEMORY.md`. Keep a
|
|
184
|
+
tombstone (routine name + retirement date + reason). When mining (Step 2), if a re-detected
|
|
185
|
+
Trigger/Inferred-action pair matches a tombstone retired **within the last 30 days**
|
|
186
|
+
(cool-off, provisional), do NOT auto-write it -- surface it as a *candidate* for the developer
|
|
187
|
+
to re-confirm. After the cool-off it may be written fresh at the initial confidence.
|
|
188
|
+
|
|
189
|
+
### Step 4 -- Promotion (propose only)
|
|
190
|
+
|
|
191
|
+
A routine observed consistently **across multiple repos** is a candidate cross-project trait
|
|
192
|
+
for user-global memory in `~/.claude/CLAUDE.md`. **Propose it -- do not auto-promote.** Present
|
|
193
|
+
the candidate and the evidence; the developer decides. The exact promotion threshold is an
|
|
194
|
+
open question in the standard and is provisional here.
|
|
195
|
+
|
|
196
|
+
### Step 5 -- Act / surface
|
|
197
|
+
|
|
198
|
+
Present the result to the developer:
|
|
199
|
+
|
|
200
|
+
1. The distilled routines (newly written and pre-existing) for this repo.
|
|
201
|
+
2. A short **"likely next steps"** list inferred from the current state and the routines.
|
|
202
|
+
3. For routines whose inferred action is mechanically actionable, **PROPOSE** (never auto-add)
|
|
203
|
+
an `[auto]` tag so the auto-worker could pre-stage it -- subject to the developer confirming
|
|
204
|
+
the tag. The `[auto]` tag is the authorization boundary; eligibility rules in
|
|
205
|
+
`standards/tooling/auto-worker-eligibility.md` still apply, and this skill never tags
|
|
206
|
+
anything itself.
|
|
207
|
+
|
|
208
|
+
After surfacing, append a completion usage record:
|
|
209
|
+
```json
|
|
210
|
+
{"component": "skill/procedural-memory", "action": "completed", "detail": "<N routines written, M candidates, K promotions proposed>", "ts": "<ISO timestamp>", "session_id": "<if known>"}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## HARD CONSTRAINTS
|
|
216
|
+
|
|
217
|
+
From `standards/workflows/procedural-memory.md` -- these are not optional:
|
|
218
|
+
|
|
219
|
+
- **A `procedural` entry is an inference, not an asserted fact.** It must remain visibly
|
|
220
|
+
distinguishable from `user`/`project` memory (which record things the developer stated), so
|
|
221
|
+
a wrong inference can be retired without eroding trust in asserted facts.
|
|
222
|
+
- **Suggest, never act.** A distilled routine may *suggest* a next step or an `[auto]` tag, but
|
|
223
|
+
it must not drive an autonomous action without a human-in-the-loop confirmation. Any routine
|
|
224
|
+
that would trigger an irreversible or shared-system action is subject to
|
|
225
|
+
`standards/workflows/hitl-gates.md` -- inference grants no authority to act.
|
|
226
|
+
- **Observe logging is opt-in, scrubbed, and machine-local (standard D2).** The Observe hook is
|
|
227
|
+
off by default; do not read the usage log to mine routines unless consent is set (see Consent
|
|
228
|
+
check). Capture only the documented allow-list -- command/tool names, file paths/types, event
|
|
229
|
+
types, durations -- and NEVER full arguments, file contents, diffs, or prompt/response text.
|
|
230
|
+
Run the scrub/redaction pass (regex for tokens/keys, emails, obvious PII; replace with typed
|
|
231
|
+
placeholders; drop a record that cannot be confidently scrubbed) BEFORE writing any record.
|
|
232
|
+
Never copy the log off the machine, into a versioned file, or into a `procedural`/promoted
|
|
233
|
+
entry -- entries store only the distilled Trigger/Inferred-action plus aggregate evidence.
|
|
234
|
+
- **Decay and retirement are mandatory (standard D1).** Every `procedural` entry carries
|
|
235
|
+
**Confidence**, **First-observed**, and **Last-observed**. Each pass re-evaluates them, retires
|
|
236
|
+
entries below the floor or past the staleness window, honours `<!-- RETIRE: -->` /
|
|
237
|
+
`<!-- CONFIRM: -->` markers, and archives (never silently deletes) retired entries with a
|
|
238
|
+
cool-off tombstone so a retired routine does not silently reappear.
|
|
239
|
+
- **Repo-relative paths only** in any versioned output. Use `~/.claude/...` solely as the
|
|
240
|
+
canonical memory location, never a developer's absolute filesystem path.
|
|
241
|
+
|
|
242
|
+
### Privacy -- what the Observe log captures, redacts, and where it lives
|
|
243
|
+
|
|
244
|
+
- **Captured:** command/tool names; file paths/types touched (repo-relative); event types and
|
|
245
|
+
`action` values; coarse durations and counts; timestamps, ISO-week, session id.
|
|
246
|
+
- **Never captured:** full command arguments; file contents or diffs; prompt/response text; the
|
|
247
|
+
literal text of corrections/redirects (only that one occurred, and its coarse type); secrets,
|
|
248
|
+
tokens, credentials, env values.
|
|
249
|
+
- **Redaction:** scrub-before-write -- regex detectors for tokens/keys (high-entropy strings,
|
|
250
|
+
`sk-`/`ghp_`/AWS-style prefixes), emails, obvious PII; matches replaced with `<REDACTED:...>`;
|
|
251
|
+
unscrubabble records dropped.
|
|
252
|
+
- **Storage/consent:** lives only at `.ai-assistance/local/kpi/usage-<YYYY-WNN>.jsonl`
|
|
253
|
+
(machine-local, gitignored, never committed). Enable via `procedural_memory.observe: true` in
|
|
254
|
+
local settings; disable by removing it; the developer may delete the log at any time.
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Example -- one mined pattern -> resulting `procedural` entry
|
|
259
|
+
|
|
260
|
+
**Observed.** Over four ISO weeks the usage log shows that in 4 of 4 sessions ending with a
|
|
261
|
+
merge to `main`, the same or next session regenerates code-specs and bumps the changelog
|
|
262
|
+
before any new branch is opened. 4 sessions >= the threshold of 3, so it is written.
|
|
263
|
+
|
|
264
|
+
Resulting file `~/.claude/projects/<project>/memory/procedural-merge-followup.md`:
|
|
265
|
+
|
|
266
|
+
```markdown
|
|
267
|
+
## Post-merge spec + changelog routine
|
|
268
|
+
|
|
269
|
+
**Trigger:** a feature branch is merged to `main`.
|
|
270
|
+
**Inferred action:** regenerate code-specs and bump the changelog before opening the next branch.
|
|
271
|
+
**Confidence:** 0.6
|
|
272
|
+
**First-observed:** 2026-06-28
|
|
273
|
+
**Last-observed:** 2026-06-28
|
|
274
|
+
|
|
275
|
+
Observed in 4 of 4 opportunities across 4 sessions (source: usage-2026-W22 ... usage-2026-W25).
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
On a later pass, if a merge to `main` is NOT followed by the spec+changelog action, Confidence
|
|
279
|
+
drops by 0.2; sustained contradiction (or a `<!-- RETIRE: Post-merge spec + changelog routine -->`
|
|
280
|
+
marker, or 90 days without observation) retires it to `memory/retired/`.
|
|
281
|
+
|
|
282
|
+
Index line added to `MEMORY.md`:
|
|
283
|
+
|
|
284
|
+
```markdown
|
|
285
|
+
- [Procedural: Post-merge spec + changelog routine](procedural-merge-followup.md) — merge to main → regenerate code-specs + bump changelog
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Surfaced at the next post-merge session as a likely next step, with a *proposal* (awaiting
|
|
289
|
+
confirmation) to tag "regenerate code-specs `[auto]`".
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## What this skill does NOT do
|
|
294
|
+
|
|
295
|
+
- Does not run the Observe stage -- it reads the usage log; it does not write session signals.
|
|
296
|
+
- Does not execute any routine, autonomously or otherwise -- surfacing only.
|
|
297
|
+
- Does not add an `[auto]` tag -- it proposes; the developer confirms.
|
|
298
|
+
- Does not auto-promote a routine to `~/.claude/CLAUDE.md` -- it proposes; the developer decides.
|
|
299
|
+
- Does not write a routine below the minimum-observation threshold.
|
|
300
|
+
- Does not read the Observe log without consent set (Observe is opt-in, off by default).
|
|
301
|
+
- Does not write any record to the usage log without first running the scrub/redaction pass.
|
|
302
|
+
- Does not capture command arguments, file contents, diffs, or prompt/response text.
|
|
303
|
+
- Does not copy machine-local log contents into any versioned or promoted file.
|
|
304
|
+
- Does not silently delete a retired routine -- it archives to `memory/retired/` with a tombstone.
|
|
305
|
+
- Does not re-write a routine retired within the cool-off window -- it surfaces it as a candidate.
|
|
306
|
+
- Does not modify `user`/`project`/`feedback`/`reference` memory entries -- it only adds and
|
|
307
|
+
maintains `procedural` entries.
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## Version note
|
|
312
|
+
|
|
313
|
+
v0.2.0 is aligned with `standards/workflows/procedural-memory.md` at v0.2.0 (`status: draft`,
|
|
314
|
+
ready for consolidation review). It implements the now-decided decay/retirement lifecycle (D1)
|
|
315
|
+
and Observe-stage privacy policy (D2). The distill cadence (weekly placeholder), the
|
|
316
|
+
minimum-observation threshold (`>= 3 sessions`), the cross-repo promotion rule, and the lifecycle
|
|
317
|
+
numbers (initial confidence 0.6, +0.1/-0.2 steps, 0.3 floor, 90-day staleness, 30-day cool-off)
|
|
318
|
+
are all provisional. They will be revisited and firmed up when the standard reaches
|
|
319
|
+
`status: reviewed`; this skill should be re-versioned to match.
|
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
{
|
|
2
|
-
"ep-ai-standards-version": "1.5.0",
|
|
3
|
-
"applied-at": "2026-06-13",
|
|
4
|
-
"project-type": [
|
|
5
|
-
"ruby"
|
|
6
|
-
],
|
|
7
|
-
"deferred": [],
|
|
8
|
-
"installed-components": {
|
|
9
|
-
"skills/code-specs": "0.0.0",
|
|
10
|
-
"skills/ep-ai-manager": "2.1.0",
|
|
11
|
-
"skills/dep-graph": "0.0.0",
|
|
12
|
-
"skills/corporate-policies": "1.0.0",
|
|
13
|
-
"skills/ai-instructions": "0.0.0",
|
|
14
|
-
"skills/spec-generation": "0.0.0",
|
|
15
|
-
"skills/gemini-assist": "0.0.0",
|
|
16
|
-
"skills/ruby-scripting": "0.1.0",
|
|
17
|
-
"skills/refactor": "0.0.0",
|
|
18
|
-
"skills/project-cycle": "0.0.0",
|
|
19
|
-
"skills/graphql-schema-analysis": "0.0.0"
|
|
20
|
-
|
|
1
|
+
{
|
|
2
|
+
"ep-ai-standards-version": "1.5.0",
|
|
3
|
+
"applied-at": "2026-06-13",
|
|
4
|
+
"project-type": [
|
|
5
|
+
"ruby"
|
|
6
|
+
],
|
|
7
|
+
"deferred": [],
|
|
8
|
+
"installed-components": {
|
|
9
|
+
"skills/code-specs": "0.0.0",
|
|
10
|
+
"skills/ep-ai-manager": "2.1.0",
|
|
11
|
+
"skills/dep-graph": "0.0.0",
|
|
12
|
+
"skills/corporate-policies": "1.0.0",
|
|
13
|
+
"skills/ai-instructions": "0.0.0",
|
|
14
|
+
"skills/spec-generation": "0.0.0",
|
|
15
|
+
"skills/gemini-assist": "0.0.0",
|
|
16
|
+
"skills/ruby-scripting": "0.1.0",
|
|
17
|
+
"skills/refactor": "0.0.0",
|
|
18
|
+
"skills/project-cycle": "0.0.0",
|
|
19
|
+
"skills/graphql-schema-analysis": "0.0.0",
|
|
20
|
+
"skills/procedural-memory": "0.2.0"
|
|
21
|
+
}
|
|
21
22
|
}
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,125 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.3.12] - 2026-07-09
|
|
6
|
+
|
|
7
|
+
Compat-layer correctness for register **field filters** + the native `SearchConf` field-filter DSL.
|
|
8
|
+
**Backwards-compatible** — bug fixes (broken field filters returned 0 results) + additive methods;
|
|
9
|
+
no public return type changed. (The `get_by_name`→collection contract change is intentionally **not**
|
|
10
|
+
in this release — it is a breaking change parked on `feature/model-input-fixes` for a deliberate,
|
|
11
|
+
signed-off future decision.)
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **`Compat::FilterTranslator`** now routes register **FIELD** filters to the backend-correct ES
|
|
16
|
+
operation (previously emitted the system-key operation → 0 results):
|
|
17
|
+
- Date FIELD (key `date.zXXXX`) → `range_date_filter` + `path: membranes.date` (system date keeps
|
|
18
|
+
`date_filter`).
|
|
19
|
+
- Select FIELD (key `select_str.zXXXX`) → `has_any_filter` / `doesnt_have_any_filter` +
|
|
20
|
+
`path: membranes.select_str` + `field_key: 'selected'` (system option key keeps
|
|
21
|
+
`one_of_filter`/`none_of_filter`).
|
|
22
|
+
- `exact_filter` no longer derives a `membranes.<type>` path for **system** keys
|
|
23
|
+
(`external_id`/`id`/`state`) — a spurious path produced term `membranes.external_id.external_id`
|
|
24
|
+
→ 0 results (silent miss → dup-on-upsert). Register FIELD keys still get the nested path.
|
|
25
|
+
- Verified against the backend filter definitions; catalogued in
|
|
26
|
+
`.ai-assistance/code/filter_contract_matrix.md`.
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- **`SearchConf` field-filter DSL:** `sc[:'date.zXXXX'].between/since/before` now emits
|
|
31
|
+
`range_date_filter` + `membranes.date` for register Date FIELDs; new `FieldRef#any_of` / `#none_of`
|
|
32
|
+
→ `has_any_filter` / `doesnt_have_any_filter` (path + `field_key`) for register field value
|
|
33
|
+
membership (distinct from `one_of`, which ORs `exact_filter` for system keys).
|
|
34
|
+
- **`get_by_id`** on `DataField::Collection` and `SectionCollection` (v2-compat find-by-id) — fixes
|
|
35
|
+
`NoMethodError` in consumers that resolve a field/section by id.
|
|
36
|
+
|
|
37
|
+
## [1.3.11] - 2026-07-04
|
|
38
|
+
|
|
39
|
+
Template automatic **build & maintenance** engine (backwards-compatible — a self-contained new
|
|
40
|
+
`Diff` module + a build emitter; nothing existing changed). Validated **offline** (specs + fixtures +
|
|
41
|
+
shapes checked against the live schema dump); the live UAT→PROD round trip is pending a sandbox org.
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- **`genomeSignature`** fetched on every data-field type (added once to the `dataFieldInterface`
|
|
46
|
+
fragment, `@skip(if: $only_content)`) + `passthrough :genomeSignature` on `Base::Page::DataField` —
|
|
47
|
+
a strong-but-fallible field-pairing signal.
|
|
48
|
+
- **`Diff::VersionDiff`** — two same-object (retained-id) template snapshots → an exact structural
|
|
49
|
+
changelog: added/removed/changed/moved for stages, sections, fields (label/type/section-move),
|
|
50
|
+
select options (label/weight), **gauge stops** (add/remove/threshold/color, matched by stop id), and
|
|
51
|
+
typed **`byType` field config** (conservative, only confirmed read↔input-key matches: Gauge `max`;
|
|
52
|
+
Select `dataType/multiple/flat/other/otherDesc`; Date `showTime/pastOnly/todayButton`).
|
|
53
|
+
- **`Diff::Change`** — command-ready change (`op`/`kind`/`id`/`label`/`path`/`attribute`/`before`/
|
|
54
|
+
`after`/`parent_id`/`by_type`) with a human `#description`; `#to_h` is the stable interchange shape.
|
|
55
|
+
- **`Diff::CommandSynthesizer`** — a `Change` set → an ordered `WorkflowCommand` batch (the replayable
|
|
56
|
+
"commit"): moves/renames/config, options, gauge stops, `editFieldConfiguration(byType:)`, with
|
|
57
|
+
**`placeholderId` threading** so dependent intra-batch creates reference not-yet-created nodes.
|
|
58
|
+
Genuinely ambiguous cases (field type change, moves without a target id) are left **UNSUPPORTED** —
|
|
59
|
+
never guessed.
|
|
60
|
+
- **`Diff::Deploy`** — `from_versions(before, after, target_doc:)` / `from_cross_object(...)` produce
|
|
61
|
+
the ordered batch ready for `executeWorkflowCommands`; `#execute!` refuses to run while the honest
|
|
62
|
+
`unsupported` list is non-empty unless `allow_partial: true`; inert until an executor is passed.
|
|
63
|
+
- **`Diff::IdResolver`** — indexes a target doc's stage names + section headings → ids for move
|
|
64
|
+
resolution; duplicate keys resolve to `nil` (never guesses).
|
|
65
|
+
- **`Diff::Pairing::{Engine,Signals,Candidate,Ledger}`** — multi-signal equivalence matching for
|
|
66
|
+
cross-object templates (genome 0.5 + type 0.2 + label 0.2 + options-by-value 0.1, averaged over
|
|
67
|
+
applicable signals; greedy 1:1; auto-accept ≥0.85, ambiguous 0.5–0.85, unmatched <0.5; genome
|
|
68
|
+
mismatch scores 0 but does **not** veto). `Ledger` persists confirmed pairs (consulted first;
|
|
69
|
+
human corrections supersede).
|
|
70
|
+
- **`Diff::Strategy`** — composable diff modalities: pairing (`:id`/`:genome`/`:type_label`/
|
|
71
|
+
`:assisted`) × scope (`:structural`/`:config_only`/`:data_migration`) × move-sensitivity × intent
|
|
72
|
+
(`:changelog`/`:deploy`/`:sync_readiness`). `.default` reproduces exact pre-existing behaviour.
|
|
73
|
+
- **`Diff::CrossObjectDiff`** — diffs two templates with **no shared ids** by building the
|
|
74
|
+
id-correspondence map via `Pairing::Engine` (+ optional `Ledger`), then emitting the same `Change`
|
|
75
|
+
output that feeds `CommandSynthesizer`/`Deploy`. Ambiguous/unmatched held in `#unresolved` for a
|
|
76
|
+
human — never auto-paired.
|
|
77
|
+
- **`Builder::TemplateBuilder`** — a declarative template spec (stages→sections→fields→options→
|
|
78
|
+
config→gauge-stops) → an ordered `WorkflowCommand` batch for `Builder::Template#create/update`,
|
|
79
|
+
using the **same `placeholderId` threading** as the diff synthesizer so build-from-scratch and
|
|
80
|
+
diff-deploy emit through one layer. Emits only verified input `VALID_KEYS`. A field's `description`
|
|
81
|
+
(e.g. a CSV/hidden-field identity token) is emitted as a follow-up `editFieldConfiguration(
|
|
82
|
+
dataFieldId:, description:)` — the correct schema seam, since `WorkflowAddFieldInput` has no
|
|
83
|
+
`description` key.
|
|
84
|
+
- **Stage/section back-refs on added nodes** (`Diff::CommandSynthesizer`) — an added field's `addField`
|
|
85
|
+
now carries `sectionId` (`Change#parent_id`) + `stageId` (new `Change#owner_id`); an added section
|
|
86
|
+
emits a follow-up `addStageSection(stageId:, sectionId:)`. All threaded via `ref()` (parent
|
|
87
|
+
placeholder when created same-batch, else real id; omitted when unknown → historical behaviour
|
|
88
|
+
unchanged). `VersionDiff` records `parent_id`/`owner_id` on added field/section changes.
|
|
89
|
+
|
|
90
|
+
### Fixed
|
|
91
|
+
|
|
92
|
+
- **Fragment references migrated to the `spread :Name` registry convention.** The Action and
|
|
93
|
+
ContractorEntity **mutations** (`create`/`update`/`destroy`, `create`/`update`/`archive`) still used
|
|
94
|
+
the dead `___Const__Fragment` convention, which resolves a Ruby constant `Fragment::<Name>` that no
|
|
95
|
+
longer exists (fragments are a registry now) → `uninitialized constant … Fragment::… (NameError)` at
|
|
96
|
+
render time. Now `spread :Action` / `spread :ContractorEntity`, matching the already-migrated queries.
|
|
97
|
+
(The sibling breakage in eco-helpers' location-command optimizations is fixed in eco-helpers 3.2.17;
|
|
98
|
+
it crashed the live act-gov locations sync.)
|
|
99
|
+
- **Kickstand workflow mutations — bare `DateTime` selection.** `Kickstand::{Start,Stop,Fail}Workflow`
|
|
100
|
+
selected `startedAt`/`stoppedAt`/`failedAt` bare → "Field must have selections". Now
|
|
101
|
+
`{ dateTime timeZone }` (same class as the 1.3.10 LocationStructure fix).
|
|
102
|
+
- **`tests/validate_queries.rb` now renders MUTATIONS too** (was queries only) and **hard-fails on a
|
|
103
|
+
render error** (dead fragment / unresolved constant), not just a soft skip — the offline guard for
|
|
104
|
+
both classes above. It caught the 3 Kickstand bugs immediately.
|
|
105
|
+
|
|
106
|
+
### Schema realities (verified against the live introspection dump)
|
|
107
|
+
|
|
108
|
+
- **`required` cannot be set via the workflow command bus** — there is NO `required` input key anywhere
|
|
109
|
+
in the schema (not on `WorkflowAddFieldInput`, not on `WorkflowEditFieldConfigurationInput` or any of
|
|
110
|
+
its 12 byType sub-inputs). Callers must treat field-`required` as **read-only / out-of-band**
|
|
111
|
+
(ecoportal-qa `:skip`s `required`-readiness by design).
|
|
112
|
+
|
|
113
|
+
### Dependencies
|
|
114
|
+
|
|
115
|
+
- **Requires `ecoportal-api-v2 >= 3.3.3`** (was `>= 3.3.2`). 3.3.2 has a Ruby-3.x `TypeError` in the
|
|
116
|
+
`DoubleModel` cascade (`_cascaded_attributes_trace`) that crashes `as_update`/`DiffService` on any
|
|
117
|
+
model with nested attributes — fixed in v2 3.3.3. Raising the floor stops the broken v2 from
|
|
118
|
+
resolving on consumers.
|
|
119
|
+
|
|
120
|
+
### Known gaps (tracked, not in this release)
|
|
121
|
+
|
|
122
|
+
- Live characterization (UAT→PROD replay + verify) is pending a sandbox org + credentials.
|
|
123
|
+
|
|
5
124
|
## [1.3.10] - 2026-07-03
|
|
6
125
|
|
|
7
126
|
Hotfix (backwards-compatible). Resolves a live failure on the Turners & Growers users sync.
|
data/CLAUDE.md
CHANGED
|
@@ -11,8 +11,17 @@ docs/worklog.md ← current state, blockers, open quest
|
|
|
11
11
|
.ai-assistance/projects/<slug>/TODO.md ← active project task list
|
|
12
12
|
.ai-assistance/local/paths.json ← local paths to sibling repos (gitignored — machine-specific)
|
|
13
13
|
.ai-assistance/bridge/CLAUDE.md ← bridge protocol: format, lifecycle, cross-repo requests
|
|
14
|
+
.ai-assistance/code/ecoPortal_architecture/ ← VERIFIED PLATFORM KNOWLEDGE — how the platform behaves
|
|
15
|
+
(data model, API layers, page/stage workflows, fields, search).
|
|
16
|
+
Read 00_overview_and_index first, then the area file for the
|
|
17
|
+
task at hand, BEFORE implementing platform logic. See ADR-012.
|
|
14
18
|
```
|
|
15
19
|
|
|
20
|
+
> Platform behaviour is documented in `ecoPortal_architecture/` for a reason: do not infer a
|
|
21
|
+
> stage/workflow/field rule from code alone when a verified note exists. If you confirm a new
|
|
22
|
+
> platform fact, add it to the relevant doc with its evidence (`file:line` or "confirmed by
|
|
23
|
+
> <user> on <date>") in the same session -- that tree is the durable, shared home.
|
|
24
|
+
|
|
16
25
|
---
|
|
17
26
|
|
|
18
27
|
## Repository Role
|
|
@@ -95,6 +104,7 @@ the developer explicitly requests it for a specific commit.
|
|
|
95
104
|
| `spec-generation` | `.ai-assistance/skills/spec-generation/SKILL.md` | Generate RSpec specs for backwards-compat |
|
|
96
105
|
| `refactor` | `.ai-assistance/skills/refactor/SKILL.md` | Identify and log refactoring opportunities |
|
|
97
106
|
| `project-cycle` | `.ai-assistance/skills/project-cycle/SKILL.md` | Project planning, TODOs, decisions |
|
|
107
|
+
| `procedural-memory` | `.ai-assistance/skills/procedural-memory/SKILL.md` | Distill recurring work routines and surface likely next steps |
|
|
98
108
|
|
|
99
109
|
---
|
|
100
110
|
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: "1.0"
|
|
3
|
+
repo: "ecoportal-api-graphql"
|
|
4
|
+
doc: architecture
|
|
5
|
+
last_generated: "2026-07-06"
|
|
6
|
+
source_head: "2abd6fc"
|
|
7
|
+
review_status: draft
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Architecture -- ecoportal-api-graphql
|
|
11
|
+
|
|
12
|
+
**Scope:** High-level structure only. Deep per-area detail lives in `.ai-assistance/code/`
|
|
13
|
+
(`code-specs`); link to it rather than duplicating.
|
|
14
|
+
|
|
15
|
+
## Top-level structure
|
|
16
|
+
|
|
17
|
+
| Directory | Role |
|
|
18
|
+
|---|---|
|
|
19
|
+
| `lib/` | The gem source. `lib/ecoportal/api/graphql/` holds the layered client; `lib/ecoportal/api/common/graphql/` holds shared utilities (HTTP client, base model, helpers, patches). |
|
|
20
|
+
| `spec/` | RSpec specs, mirroring the `lib/` structure. |
|
|
21
|
+
| `tests/` | Manual integration test scripts (live-API characterization, not the RSpec suite). |
|
|
22
|
+
| `bin/` | Development console / helper executables. |
|
|
23
|
+
| `scripts/` | Token-offload and tooling scripts (see `scripts/CLAUDE.md`). |
|
|
24
|
+
| `docs/` | Human docs, worklog, and this self-docs set. |
|
|
25
|
+
| `.ai-assistance/` | AI agent resources: code-specs, project intent/TODOs, skills, bridge, conventions. |
|
|
26
|
+
| `.claude/` | Claude Code settings and hooks for this repo. |
|
|
27
|
+
|
|
28
|
+
## Key components
|
|
29
|
+
|
|
30
|
+
Reused from `.ai-assistance/code/OVERVIEW.md` and `.ai-assistance/code/ecoPortal_architecture/`;
|
|
31
|
+
not re-analysed here.
|
|
32
|
+
|
|
33
|
+
- **Main class `Ecoportal::API::GraphQL`** (`lib/ecoportal/api/graphql.rb`) -- the public entry
|
|
34
|
+
point, instantiated with credentials (email, pass, org_id, host). Exposes builders and
|
|
35
|
+
convenience shortcuts per domain.
|
|
36
|
+
- **`Common::GraphQL::Client`** (`lib/ecoportal/api/common/graphql/client.rb`) -- the HTTP layer,
|
|
37
|
+
extending `Graphlient::Client`. Handles auth (`AuthService`), org context, and timeouts;
|
|
38
|
+
`no_schema: true` is always passed, so schema introspection is disabled and queries are not
|
|
39
|
+
validated against a schema at build time.
|
|
40
|
+
- **Layered namespace** under `Ecoportal::API::GraphQL::` (folder mirrors module exactly):
|
|
41
|
+
`Builder` (developer-facing facade per domain) -> `Query` / `Mutation` (operation definitions)
|
|
42
|
+
-> `Logic` (execution: base_query, base_model, payload, input, connection) -> `Fragment`
|
|
43
|
+
(fragment strings) -> `Model` (read-side response models), `Input` / `Payload` (write side) ->
|
|
44
|
+
`Base` (shared base classes), `Interface` (GraphQL interface types) -> `Common::GraphQL::Client`.
|
|
45
|
+
- **`Compat::` layer** -- v2 compatibility shims (`Pages`, `Registers`, `StageView`,
|
|
46
|
+
`StageCollection`, etc.) that let `eco-helpers` treat `graphql` as a drop-in for the older `apiv2`
|
|
47
|
+
interface.
|
|
48
|
+
- **`Diff::` and `Builder::TemplateBuilder`** -- the template build-and-maintenance engine
|
|
49
|
+
(self-version and cross-object diff, pairing engine + ledger, `Change`-to-`WorkflowCommand`
|
|
50
|
+
synthesis, unified BUILD emitter). This is where current development is concentrated.
|
|
51
|
+
|
|
52
|
+
## How they fit
|
|
53
|
+
|
|
54
|
+
A consumer instantiates `Ecoportal::API::GraphQL` with credentials, then calls a `Builder` for the
|
|
55
|
+
domain it wants (page, template, action, contractor entity, location structure). The builder
|
|
56
|
+
composes `Query`/`Mutation` operations, which the `Logic` layer executes through
|
|
57
|
+
`Common::GraphQL::Client` over HTTP. Fragments are assembled at query build time
|
|
58
|
+
(`BaseQuery#assemble_fragments` scans query strings for `...FragmentName` spreads). Responses parse
|
|
59
|
+
into `Model` objects (read side); mutations take `Input` objects and return `Payload` objects
|
|
60
|
+
(write side). The `Compat` layer re-exposes this so downstream `eco-helpers` scripts keep working
|
|
61
|
+
unchanged.
|
|
62
|
+
|
|
63
|
+
## Entry points
|
|
64
|
+
|
|
65
|
+
- `require 'ecoportal/api-graphql'` loads `ecoportal-api-v2` (and transitively `ecoportal-api`),
|
|
66
|
+
the version file, `ecoportal/api/common.graphql`, then `ecoportal/api/graphql`.
|
|
67
|
+
- Runtime entry is `Ecoportal::API::GraphQL.new(email:, pass:, org_id:, host:)`.
|
|
68
|
+
|
|
69
|
+
## Build / test tooling
|
|
70
|
+
|
|
71
|
+
- Build: RubyGems / Bundler. Gem spec: `ecoportal-api-graphql.gemspec`. Version constant:
|
|
72
|
+
`Ecoportal::API::GRAPQL_VERSION`.
|
|
73
|
+
- Tests: RSpec (`bundle exec rspec`). Live AI tests are `--tag live` and require `ANTHROPIC_API_KEY`
|
|
74
|
+
loaded from `.env` via `dotenv`.
|
|
75
|
+
- CI: no CI config file was detected at the repo root by the scanner (`ci_files: []`).
|
|
76
|
+
<!-- TODO(human): confirm whether CI runs elsewhere (e.g. GitLab CI defined outside root) or is absent. -->
|
|
77
|
+
|
|
78
|
+
## Links to detailed docs
|
|
79
|
+
|
|
80
|
+
- `.ai-assistance/code/OVERVIEW.md` -- gem overview, entry points, namespace convention.
|
|
81
|
+
- `.ai-assistance/code/ecoPortal_architecture/00_overview_and_index.md` -- verified platform
|
|
82
|
+
knowledge index (data model, API layers, page/stage workflows, fields, search).
|
|
83
|
+
- `.ai-assistance/code/ecoPortal_architecture/11_integration_gems.md` -- the integration gem stack.
|
|
84
|
+
- `.ai-assistance/code/dependencies.md` -- full dependency map (remotes, fork relationships).
|
|
85
|
+
- `.ai-assistance/code/diff_pairing_engine.md`, `.ai-assistance/code/diff_service_deep_dive.md`,
|
|
86
|
+
`.ai-assistance/code/template_diff_pairing_domain.md` -- the template diff/build engine.
|
|
87
|
+
- `.ai-assistance/code/data_fields.md`, `.ai-assistance/code/graphql_domain_knowledge.md`,
|
|
88
|
+
`.ai-assistance/code/schema_analysis.md` -- data-field and schema detail.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{"ts": "2026-07-06T11:14:43Z", "file": "docs/self-docs/OVERVIEW.md", "change": "created", "from_hash": null, "to_hash": "a43c976a85ebfad6"}
|
|
2
|
+
{"ts": "2026-07-06T11:14:43Z", "file": "docs/self-docs/ARCHITECTURE.md", "change": "created", "from_hash": null, "to_hash": "b0989977a912aab1"}
|
|
3
|
+
{"ts": "2026-07-06T11:14:43Z", "file": "docs/self-docs/CONVENTIONS.md", "change": "created", "from_hash": null, "to_hash": "1649159eb799a7b8"}
|
|
4
|
+
{"ts": "2026-07-06T11:14:43Z", "file": "docs/self-docs/INTEGRATIONS.md", "change": "created", "from_hash": null, "to_hash": "bae9f91748e33af1"}
|
|
5
|
+
{"ts": "2026-07-06T11:14:43Z", "file": "docs/self-docs/STATUS.md", "change": "created", "from_hash": null, "to_hash": "08841d1d45eea2d6"}
|
|
6
|
+
{"ts": "2026-07-06T11:15:00Z", "file": "docs/self-docs/OVERVIEW.md", "change": "updated", "from_hash": "a43c976a85ebfad6", "to_hash": "391055c9a6a687b9"}
|
|
7
|
+
{"ts": "2026-07-06T11:15:00Z", "file": "docs/self-docs/ARCHITECTURE.md", "change": "updated", "from_hash": "b0989977a912aab1", "to_hash": "ad05f25b95b49c00"}
|