ecoportal-api-graphql 1.3.13 → 1.3.15

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.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/.ai-assistance/bridge/archive/oscar-a1b2c3d-gitlab-mcp-doc-update.inbox.md +29 -29
  3. data/.ai-assistance/bridge/archive/oscar-c912c25-gemini-design-review.inbox.md +42 -42
  4. data/.ai-assistance/projects/TODO.md +170 -118
  5. data/.ai-assistance/skills/ai-instructions/SKILL.md +48 -48
  6. data/.ai-assistance/skills/code-specs/SKILL.md +69 -69
  7. data/.ai-assistance/skills/gemini-assist/SKILL.md +63 -63
  8. data/.ai-assistance/skills/project-cycle/SKILL.md +177 -177
  9. data/.ai-assistance/skills/refactor/SKILL.md +62 -62
  10. data/.ai-assistance/skills/spec-generation/SKILL.md +72 -72
  11. data/.gitignore +37 -37
  12. data/.gitlab-ci.yml +64 -12
  13. data/CHANGELOG.md +77 -0
  14. data/changelog.d/fixed-mr51-payload-item-mismatches.md +17 -0
  15. data/docs/worklog.md +0 -18
  16. data/lib/ecoportal/api/common/graphql/client.rb +0 -2
  17. data/lib/ecoportal/api/common/graphql/http_client.rb +6 -0
  18. data/lib/ecoportal/api/graphql/base/ai_summary_version.rb +17 -17
  19. data/lib/ecoportal/api/graphql/base/location_classification_type.rb +15 -15
  20. data/lib/ecoportal/api/graphql/base/location_structure.rb +27 -27
  21. data/lib/ecoportal/api/graphql/base/organization.rb +15 -15
  22. data/lib/ecoportal/api/graphql/base/page/task.rb +24 -0
  23. data/lib/ecoportal/api/graphql/base/page.rb +17 -16
  24. data/lib/ecoportal/api/graphql/base/template.rb +35 -0
  25. data/lib/ecoportal/api/graphql/base.rb +37 -35
  26. data/lib/ecoportal/api/graphql/builder/contractor_entity.rb +41 -41
  27. data/lib/ecoportal/api/graphql/compat/response.rb +35 -35
  28. data/lib/ecoportal/api/graphql/connection/action.rb +11 -11
  29. data/lib/ecoportal/api/graphql/connection/action_category.rb +11 -11
  30. data/lib/ecoportal/api/graphql/connection/contractor_entity.rb +11 -11
  31. data/lib/ecoportal/api/graphql/connection/page.rb +11 -11
  32. data/lib/ecoportal/api/graphql/connection/person_member.rb +11 -11
  33. data/lib/ecoportal/api/graphql/connection/preview_page.rb +11 -11
  34. data/lib/ecoportal/api/graphql/connection.rb +17 -17
  35. data/lib/ecoportal/api/graphql/file_upload/client.rb +21 -10
  36. data/lib/ecoportal/api/graphql/fragment/field_configuration.rb +38 -0
  37. data/lib/ecoportal/api/graphql/fragment/force.rb +14 -10
  38. data/lib/ecoportal/api/graphql/fragment/location_node.rb +26 -26
  39. data/lib/ecoportal/api/graphql/fragment/page_task.rb +39 -0
  40. data/lib/ecoportal/api/graphql/fragment/template.rb +51 -0
  41. data/lib/ecoportal/api/graphql/fragment.rb +3 -0
  42. data/lib/ecoportal/api/graphql/input/contractor_entity.rb +14 -14
  43. data/lib/ecoportal/api/graphql/input/workflow_command/add_stage.rb +18 -18
  44. data/lib/ecoportal/api/graphql/input/workflow_command/edit_field_configuration.rb +21 -21
  45. data/lib/ecoportal/api/graphql/input/workflow_command/edit_page.rb +28 -28
  46. data/lib/ecoportal/api/graphql/input/workflow_command/edit_page_creator_permissions.rb +18 -18
  47. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/cross_reference.rb +23 -23
  48. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/date.rb +20 -20
  49. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/image_gallery.rb +20 -20
  50. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/plain_text.rb +20 -20
  51. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/rich_text.rb +20 -20
  52. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/select.rb +20 -20
  53. data/lib/ecoportal/api/graphql/input/workflow_command/move_field.rb +18 -18
  54. data/lib/ecoportal/api/graphql/input/workflow_command/reorder_forces.rb +18 -18
  55. data/lib/ecoportal/api/graphql/input/workflow_command/reorder_section.rb +18 -18
  56. data/lib/ecoportal/api/graphql/input/workflow_command.rb +251 -251
  57. data/lib/ecoportal/api/graphql/input.rb +24 -24
  58. data/lib/ecoportal/api/graphql/logic/connection.rb +34 -34
  59. data/lib/ecoportal/api/graphql/model/page/task.rb +16 -0
  60. data/lib/ecoportal/api/graphql/model/page.rb +16 -15
  61. data/lib/ecoportal/api/graphql/model/person_member.rb +15 -15
  62. data/lib/ecoportal/api/graphql/model/template.rb +15 -0
  63. data/lib/ecoportal/api/graphql/model.rb +32 -30
  64. data/lib/ecoportal/api/graphql/mutation/ai_summary/generate.rb +45 -45
  65. data/lib/ecoportal/api/graphql/mutation/ai_summary/submit_feedback.rb +40 -40
  66. data/lib/ecoportal/api/graphql/mutation/contractor_entity.rb +14 -14
  67. data/lib/ecoportal/api/graphql/mutation/page/approve_review_task.rb +40 -40
  68. data/lib/ecoportal/api/graphql/mutation/page/batch_update_review_task.rb +38 -40
  69. data/lib/ecoportal/api/graphql/mutation/page/create_draft.rb +38 -40
  70. data/lib/ecoportal/api/graphql/mutation/page/delete_draft.rb +38 -40
  71. data/lib/ecoportal/api/graphql/mutation/page/execute_force_commands.rb +7 -7
  72. data/lib/ecoportal/api/graphql/mutation/page/execute_workflow_commands.rb +8 -7
  73. data/lib/ecoportal/api/graphql/mutation/page/publish_draft.rb +38 -40
  74. data/lib/ecoportal/api/graphql/mutation/page/reject_review_task.rb +40 -40
  75. data/lib/ecoportal/api/graphql/mutation/page/restart_review_task.rb +40 -40
  76. data/lib/ecoportal/api/graphql/mutation/page/undo_review_task.rb +40 -40
  77. data/lib/ecoportal/api/graphql/mutation/preset_view/destroy.rb +34 -35
  78. data/lib/ecoportal/api/graphql/mutation/register/destroy.rb +35 -35
  79. data/lib/ecoportal/api/graphql/mutation/smart_fill/generate.rb +36 -36
  80. data/lib/ecoportal/api/graphql/mutation/smart_fill/submit_feedback.rb +40 -40
  81. data/lib/ecoportal/api/graphql/mutation/smart_fill.rb +13 -13
  82. data/lib/ecoportal/api/graphql/mutation/template/create_related_page.rb +46 -46
  83. data/lib/ecoportal/api/graphql/mutation/template/destroy_related_page.rb +1 -1
  84. data/lib/ecoportal/api/graphql/mutation/template/update_information.rb +1 -1
  85. data/lib/ecoportal/api/graphql/mutation.rb +20 -20
  86. data/lib/ecoportal/api/graphql/payload/contractor_entity.rb +14 -14
  87. data/lib/ecoportal/api/graphql/payload/ok_payload.rb +36 -21
  88. data/lib/ecoportal/api/graphql/payload/page/draft.rb +26 -13
  89. data/lib/ecoportal/api/graphql/payload/page/review_task.rb +13 -13
  90. data/lib/ecoportal/api/graphql/payload/page/review_task_batch.rb +23 -0
  91. data/lib/ecoportal/api/graphql/payload/page.rb +20 -19
  92. data/lib/ecoportal/api/graphql/payload/preset_view.rb +15 -11
  93. data/lib/ecoportal/api/graphql/payload/register.rb +15 -11
  94. data/lib/ecoportal/api/graphql/payload/template/create_related_page.rb +1 -1
  95. data/lib/ecoportal/api/graphql/payload/template/destroy_related_page.rb +1 -1
  96. data/lib/ecoportal/api/graphql/payload/template/update_information.rb +1 -1
  97. data/lib/ecoportal/api/graphql/query/location_structures.rb +57 -57
  98. data/lib/ecoportal/api/graphql/query/page_with_forces.rb +9 -3
  99. data/lib/ecoportal/api/graphql/query/pages_workflow_commands.rb +9 -3
  100. data/lib/ecoportal/api/graphql/query/register_preset_views.rb +78 -78
  101. data/lib/ecoportal/api/graphql/query.rb +27 -27
  102. data/lib/ecoportal/api/graphql.rb +9 -5
  103. data/lib/ecoportal/api/graphql_version.rb +1 -1
  104. data/tests/dump_schema.rb +88 -0
  105. data/tests/validate_queries.rb +34 -12
  106. metadata +11 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fba9a366d06303f179c6b7d841930a66a29b6cc3fe836e06b218b95873bbe77e
4
- data.tar.gz: 6114ba779317ec55b649e1f7df685c0140573cea073aa07c04b9e4cfa20b433a
3
+ metadata.gz: 43397010b997d3427eda7b91683044467b679ad72fdea66e910ddf1f8eda6828
4
+ data.tar.gz: 2d1540686b0e07fbf06f56fb2ff922302fee08a35a9370b18794401c66ec50da
5
5
  SHA512:
6
- metadata.gz: d867c896796e9107870a2a49e3cdc75275b0a96559a9b8fe47fedea407ef639f7ff558ce22de798f79f3f011c7d4464a3eacd01a63e764778d2e0359cd8ed4ad
7
- data.tar.gz: c29f555f19fc3d679f51cb512c417caca1e7e5f0006e9ac35a7ccf4d7f074095011ad4a59128a458b69c178dd538d79bf952d1b26b1557397e0d5fc4c41274d4
6
+ metadata.gz: 7623eede099dbce829d5b1bba47f775926c5dfdf5e56f1a407514bb68360af8b25c0a83375983b09e4767a52dec947a313859dc2c8cff61f27476a0d703af2ff
7
+ data.tar.gz: a42d2dfec504502bf95a3bbe614c39d3f64499f2996f242d8c48afb325554f542332b9ec4110fb58e61b07ce345a63d30e6193990980b0f68860bbe17baf8cf7
@@ -1,29 +1,29 @@
1
- # TASK: Update gitlab-mcp.md with new PAT scopes and rotation info
2
-
3
- STATUS: PENDING
4
- CREATED: 2026-06-04T00:00:00Z
5
- FROM: cowork
6
- TO: code
7
-
8
- ## File to update
9
-
10
- `.claude/integrations/gitlab-mcp.md`
11
-
12
- ## Changes
13
-
14
- ### Scopes table — replace entirely
15
-
16
- | `read_api` | Read MRs, issues, diffs, repository metadata |
17
- | `read_repository`| Clone and read repository contents |
18
- | `create_runner` | Register GitLab CI runners |
19
- | `ai_features` | Access GitLab AI/Duo endpoints |
20
-
21
- ### PAT creation note — replace
22
-
23
- Enable **rotation** at creation time.
24
- **Token rotation:** Current token expires **April 2027**. When rotating, update
25
- in both `.env` and `claude_desktop_config.json`.
26
-
27
- ### "What it doesn't provide" — remove pipeline management item
28
-
29
- `create_runner` + `ai_features` scopes now partially cover CI and AI capabilities.
1
+ # TASK: Update gitlab-mcp.md with new PAT scopes and rotation info
2
+
3
+ STATUS: PENDING
4
+ CREATED: 2026-06-04T00:00:00Z
5
+ FROM: cowork
6
+ TO: code
7
+
8
+ ## File to update
9
+
10
+ `.claude/integrations/gitlab-mcp.md`
11
+
12
+ ## Changes
13
+
14
+ ### Scopes table — replace entirely
15
+
16
+ | `read_api` | Read MRs, issues, diffs, repository metadata |
17
+ | `read_repository`| Clone and read repository contents |
18
+ | `create_runner` | Register GitLab CI runners |
19
+ | `ai_features` | Access GitLab AI/Duo endpoints |
20
+
21
+ ### PAT creation note — replace
22
+
23
+ Enable **rotation** at creation time.
24
+ **Token rotation:** Current token expires **April 2027**. When rotating, update
25
+ in both `.env` and `claude_desktop_config.json`.
26
+
27
+ ### "What it doesn't provide" — remove pipeline management item
28
+
29
+ `create_runner` + `ai_features` scopes now partially cover CI and AI capabilities.
@@ -1,42 +1,42 @@
1
- # TASK: Gemini design review of CoWork↔Code bridge architecture
2
- STATUS: PENDING
3
- CREATED: 2026-06-03T00:00:00Z
4
- FROM: cowork
5
- TO: code
6
-
7
- ## Context
8
- We have designed a file-based bridge system for bidirectional communication between
9
- Claude in CoWork and Claude Code. The bridge lives in .claude/bridge/ inside a git repo.
10
-
11
- Architecture summary:
12
- - Inbox/outbox pattern with UUID+username prefixed filenames (no merge conflicts)
13
- - Scripts (bash + TypeScript) handle file ops, env detection, UUID gen — offloading work from AI tokens
14
- - CLAUDE.md files in each subfolder give each agent scoped instructions
15
- - capabilities/ folder tracks what each environment can do, with a dated assumptions log
16
- - conventions/ folder defines gitignore rules and instruction file structure
17
- - capabilities-check.ts runs periodically using Haiku to flag stale assumptions
18
-
19
- Key design decisions:
20
- - Each agent checks capabilities before bridging (only bridge what you can't do yourself)
21
- - Archive is committed to git — it's the audit trail
22
- - Draft tasks (.draft.md) are gitignored — local-only until pushed
23
- - Code processes only its own username-prefixed tasks
24
-
25
- ## Request
26
- Use the Gemini connector (or Gemini API if available) to get an independent review of
27
- this architecture. Ask Gemini:
28
-
29
- 1. What are the weaknesses or failure modes of this design?
30
- 2. Is the token-offloading strategy (scripts vs AI prose) well-scoped, or are there gaps?
31
- 3. Are there simpler or more robust alternatives for any part of this?
32
- 4. Anything we haven't considered — especially around git workflows, multi-agent coordination,
33
- or long-term maintenance?
34
-
35
- If Gemini connector is not available, use web search to find prior art on
36
- file-based agent coordination patterns and report what you find.
37
-
38
- ## Expected output
39
- - Gemini's (or research-based) critique: weaknesses, gaps, alternatives
40
- - Your own assessment: do you agree with the critique? What would you change?
41
- - Specific suggested amendments to the design (if any)
42
- - Update capabilities/connectors.md with Gemini connector status after attempting this
1
+ # TASK: Gemini design review of CoWork↔Code bridge architecture
2
+ STATUS: PENDING
3
+ CREATED: 2026-06-03T00:00:00Z
4
+ FROM: cowork
5
+ TO: code
6
+
7
+ ## Context
8
+ We have designed a file-based bridge system for bidirectional communication between
9
+ Claude in CoWork and Claude Code. The bridge lives in .claude/bridge/ inside a git repo.
10
+
11
+ Architecture summary:
12
+ - Inbox/outbox pattern with UUID+username prefixed filenames (no merge conflicts)
13
+ - Scripts (bash + TypeScript) handle file ops, env detection, UUID gen — offloading work from AI tokens
14
+ - CLAUDE.md files in each subfolder give each agent scoped instructions
15
+ - capabilities/ folder tracks what each environment can do, with a dated assumptions log
16
+ - conventions/ folder defines gitignore rules and instruction file structure
17
+ - capabilities-check.ts runs periodically using Haiku to flag stale assumptions
18
+
19
+ Key design decisions:
20
+ - Each agent checks capabilities before bridging (only bridge what you can't do yourself)
21
+ - Archive is committed to git — it's the audit trail
22
+ - Draft tasks (.draft.md) are gitignored — local-only until pushed
23
+ - Code processes only its own username-prefixed tasks
24
+
25
+ ## Request
26
+ Use the Gemini connector (or Gemini API if available) to get an independent review of
27
+ this architecture. Ask Gemini:
28
+
29
+ 1. What are the weaknesses or failure modes of this design?
30
+ 2. Is the token-offloading strategy (scripts vs AI prose) well-scoped, or are there gaps?
31
+ 3. Are there simpler or more robust alternatives for any part of this?
32
+ 4. Anything we haven't considered — especially around git workflows, multi-agent coordination,
33
+ or long-term maintenance?
34
+
35
+ If Gemini connector is not available, use web search to find prior art on
36
+ file-based agent coordination patterns and report what you find.
37
+
38
+ ## Expected output
39
+ - Gemini's (or research-based) critique: weaknesses, gaps, alternatives
40
+ - Your own assessment: do you agree with the critique? What would you change?
41
+ - Specific suggested amendments to the design (if any)
42
+ - Update capabilities/connectors.md with Gemini connector status after attempting this
@@ -1,118 +1,170 @@
1
- # Project TODO
2
-
3
- ## Pending
4
-
5
- - [ ] **⏰ CI: query-validation step (DUE by 2026-07-17 — within 2 weeks of 2026-07-03)** — wire
6
- `tests/validate_queries.rb` into CI so the whole class of GraphQL selection bugs fails *before*
7
- release, not in a client runner. **Use a FRESHLY-introspected schema** (do NOT commit the 6.3MB
8
- dump it goes stale); fail the build only on the two structural classes ("field must have
9
- selections" / "selections can't be made on scalars"). Motivated by the 2026-07-03 v1.3.10 hotfix
10
- (LocationStructure `updatedAt`/`createdAt`) those queries had no spec and first broke in prod.
11
- Also: fix the 3 flagged union findings — **TRIAGED 2026-07-03: all THREE are REAL bugs** (verified
12
- by rendering the assembled docs + re-validating fixes; not harness/dump artifacts). Each selects
13
- fields directly on a union (invalid GraphQL) — wrap in the members' shared interface:
14
- - `Query::PageWithForces` (page_with_forces.rb:33-35): bare `forces` on `PageUnion`
15
- `... on BasePageInterface { forces { ...ForceFields } }`. ALSO `fragment ForceFields`
16
- (fragment/force.rb:15,20) selects `id` on `DataFieldBinding`/`SectionBinding` which have NO `id`
17
- (only name/reference/referenceId) → drop `id` (or use `referenceId`).
18
- - `Query::PagesWorkflowCommands` (pages_workflow_commands.rb:33-37): bare `workflow` on `PageUnion`
19
- `... on BasePageInterface { workflow { ... } }`. (The "unused variable" errors were an
20
- artifact a validator cascade from the union error; no action on the vars.)
21
- - `Query::RegisterPresetViews` (register_preset_views.rb:71): bare `{id key name weight}` on
22
- `FieldConfigurationUnion` `... on FieldConfigurationInterface { id key name weight }`.
23
- None of these 3 queries have specs add render/validation specs alongside the fixes. These are
24
- latent (not the users-sync incident); PageWithForces is WIP. Ship as a follow-up patch (1.3.11).
25
-
26
- - [x] **Builder::Register** `createRegister`, `updateRegister`, `destroyRegister` mutations.
27
- `Base::Register`, `Model::Register`, `Input::Register::Create/Update`, `Payload::Register`.
28
- `Builder::Register` with `create`, `update`, `destroy`, and `preset_view` sub-builder.
29
- `GraphQL#register` exposed (singular, distinct from `#registers` compat layer).
30
- *Done 2026-06-08*
31
-
32
- - [ ] **Dashboards / Charts** — `Register.defaultDashboardId` and dashboard queries/mutations
33
- are not yet wrapped. Backend has dashboard configuration tied to registers and organisations.
34
- Scope: `Base::Dashboard` model, `Query::Dashboard(s)`, `Builder::Register#set_default_dashboard`.
35
- Priority: medium needed when scripts need to manage register dashboard configs.
36
-
37
- - [x] **AI field mutations** — `generateAiSummary`, `generateSmartFill`,
38
- `submitAiSummaryFeedback`, `submitSmartFillFeedback` fully wrapped.
39
- `Mutation::AiSummary::Generate/SubmitFeedback`, `Mutation::SmartFill::Generate/SubmitFeedback`,
40
- `Payload::AiSummaryGenerate`, `Payload::OkPayload`, `Base::AiSummaryVersion`.
41
- `Builder::Page` wired: `generate_ai_summary`, `submit_ai_summary_feedback`,
42
- `generate_smart_fill`, `submit_smart_fill_feedback`.
43
- *Done 2026-06-08*
44
-
45
- - [ ] **AI prompt review workflow** AiSummary and SmartFill fields store an `instructions`
46
- field (the AI prompt, template-configured by humans). No audit/review workflow exists.
47
- The gem can read `field.instructions` on AiSummary/SmartFill instances already.
48
- What's needed: a way to scan pages/templates for these instructions and surface them
49
- for review. Possibly: `Query::PagesWithAiFields` + a review report script.
50
- See `.ai-assistance/code/ecoPortal_architecture/13_ai_infrastructure.md` for context.
51
- Priority: low/design — the need is real but the right interface is TBD.
52
-
53
- - [x] **eP Meta AI scaffolding project** — Standalone template repo at
54
- `C:\ruby_scripts\git\ecoPortal_ai_standards`. Bridge protocol, all scripts
55
- (lock-acquire, task-read, task-create, setup-mcps, etc.), all skills, conventions,
56
- integrations, capabilities registry, CLAUDE.md template ({{PLACEHOLDER}} vars),
57
- ONBOARDING.md (15-min setup guide), `init-project.ts` bootstrap script.
58
- Push to GitLab to share: `git@gitlab.ecoportal.co.nz:oscar/ecoPortal_ai_standards.git`
59
- *Done 2026-06-08*
60
-
61
- - [ ] **Commit unstaged changes** Large set of modified files on `ai_dev_process` branch
62
- not yet staged or committed. Review and commit once session is fully restored.
63
-
64
- ## Bridge improvements (from Gemini review 2026-06-04)
65
-
66
- - [x] **Security: Code must prompt before executing bridge-requested shell commands** —
67
- Rule added to `.ai-assistance/bridge/CLAUDE.md` "Running Code non-interactively" section.
68
- Code must surface any shell command to the user before running it, even in
69
- skip-permissions mode. User denial mark task FAILED.
70
- *Done 2026-06-08*
71
-
72
- - [x] **Atomic LOCK acquisition** — `scripts/lock-acquire.sh` implemented.
73
- Uses temp-file + hard-link (atomic on POSIX/NTFS); falls back to bash `noclobber`.
74
- Reports held-by agent/intent on contention. Auto-detects stale locks by mtime.
75
- `bridge/CLAUDE.md` updated to reference it as the preferred acquisition method.
76
- *Done 2026-06-08*
77
-
78
- - [x] **Stale IN_PROGRESS recovery** `bridge-init.sh` updated: scans for IN_PROGRESS
79
- tasks older than 1 hour (via `stat` mtime), reports them in `stale_tasks` + `stale`
80
- count in STATUS JSON. `bridge/CLAUDE.md` updated with Code's required response:
81
- report to user, ask to reset to PENDING or mark FAILED.
82
- *Done 2026-06-08*
83
-
84
- - [x] **`task-read.ts` script** — `scripts/task-read.ts` implemented.
85
- Parses all sections (title, status, created, from, to, context, request, expected,
86
- result, notes) from inbox/outbox/archive files. Searches all bridge dirs automatically.
87
- Output: structured JSON. Saves ~200 tokens per task read vs raw Markdown.
88
- *Done 2026-06-08*
89
-
90
- - [x] **Archive pruning convention** — Documented in `bridge/CLAUDE.md` "Archive pruning"
91
- section: keep last 90 days or last 50 task pairs; git history is the audit trail;
92
- prune manually when folder gets unwieldy.
93
- *Done 2026-06-08*
94
-
95
- ## File upload
96
-
97
- - [ ] **File upload** Support uploading files to attach to `File` and `ImageGallery`
98
- data fields (and potentially Action file attachments at a later stage).
99
- This is distinct from the `attach` operation (which links existing resources to
100
- a target model). Upload requires direct multipart/form-data HTTP to a separate
101
- endpoint before the GraphQL mutation references the resulting file ID.
102
- Scope:
103
- - Identify the upload endpoint and auth pattern (likely REST, not GraphQL)
104
- - Create `HttpClient#upload(file_path:, ...)` or similar
105
- - Create `Input::FileAttachment` to carry the resulting file container ID into mutations
106
- - Wire into data field update inputs (Phase E concern for fields, sooner for Actions)
107
- Priority: Medium — needed before data field updates can be fully functional.
108
- Note: Actions file attachment may be needed sooner — track separately if it becomes urgent.
109
-
110
- ## Completed
111
-
112
- - [x] **Gemini design review of bridge architecture** Done 2026-06-04. Response in
113
- `.ai-assistance/bridge/context/gemini-review-response.md`.
114
- - [x] **Regenerate GitLab PAT** — New token generated, April 2027 expiry, rotation enabled.
115
- Updated in `.env` and documented in `integrations/gitlab-mcp.md`.
116
- - [x] **Rename `.claude/` to `.ai-assistance/`** Done 2026-06-04. All references updated
117
- across scripts, CLAUDE.md, gitignore, and capabilities docs.
118
- - [x] **MCP setup script** — `setup-mcps.ts` + tests written. Teammates run once per machine.
1
+ # Project TODO
2
+
3
+ ## Pending
4
+
5
+ - [x] **CI: query-validation step** (was ⏰ DUE 2026-07-17)`tests/validate_queries.rb` is wired
6
+ into CI as the **blocking** `validate-queries` job. *Done 2026-07-29.*
7
+ - Fresh introspection at pipeline time via the new **`tests/dump_schema.rb`** (env-driven:
8
+ `SERVER` / `ORGANIZATION_ID` / `USER_EMAIL` / `USER_PASS`; `SERVER` is required on purpose
9
+ the gem's default host is PROD). No dump is committed: they go stale, and a stale schema both
10
+ invents noise and hides real findings. `validate_queries.rb` with no argument now resolves the
11
+ newest dump in the (gitignored) `.ai-assistance/tmp/`.
12
+ - **Third failing class added: "can't be made directly on unions."** This is the gap that made the
13
+ original gate insufficient: the 3 union findings landed in the advisory OTHER bucket and needed
14
+ a human to spot them. Selecting on a union without a type condition is invalid under any schema,
15
+ so it is safe to fail on unlike "field doesn't exist", which is staleness-shaped.
16
+ - **All 3 union findings now fixed** (`RegisterPresetViews` on 2026-07-26 via `dc8efc7`;
17
+ `PageWithForces` + `PagesWorkflowCommands` on 2026-07-29 via `... on BasePageInterface`), plus
18
+ the companion `fragment ForceFields` bug (`id` on a binding — `BindingInterface` has only
19
+ `name`/`referenceId`, verified in backend `types/forces/binding_interface.rb`).
20
+ - **Specs added** (render + semantic, offline, no creds): `page_with_forces_spec.rb`,
21
+ `pages_workflow_commands_spec.rb` (11 examples; verified they fail against the pre-fix code).
22
+ Each validates the rendered doc against a minimal SDL carrying the real union shape.
23
+ - **Not yet run in CI:** the job is inert until the four `EP_CI_*` CI/CD variables are set
24
+ (service account with read access on a NON-production org introspection needs no write
25
+ scope). `dump_schema.rb` has therefore never talked to a live endpoint. Its first real run is
26
+ the acceptance test for this item.
27
+
28
+ - [ ] **Force binding read/write asymmetry (found 2026-07-29 while fixing `ForceFields`)**
29
+ `WorkflowEditBindingInput` and `removeBinding` require a binding `id`, but the read side
30
+ (`Types::Forces::BindingInterface`) exposes only `name` / `referenceId` / `reference`. So
31
+ `Base::Force::Binding#id` (`passkey :id`) can never be populated, and
32
+ `Force::BindingCollection#delete!(binding_object)` sends `removeBinding: { id: nil }`.
33
+ Not fixable client-side needs `id` on the binding types (backend), or the write commands need
34
+ to key on `referenceId` + `name`. Belongs with the shape-asymmetry review project. No regression
35
+ from the fragment fix: the query that would have fed it never succeeded.
36
+ Priority: medium — silently broken write path.
37
+
38
+ - [x] **Builder::Register** — `createRegister`, `updateRegister`, `destroyRegister` mutations.
39
+ `Base::Register`, `Model::Register`, `Input::Register::Create/Update`, `Payload::Register`.
40
+ `Builder::Register` with `create`, `update`, `destroy`, and `preset_view` sub-builder.
41
+ `GraphQL#register` exposed (singular, distinct from `#registers` compat layer).
42
+ *Done 2026-06-08*
43
+
44
+ - [ ] **Dashboards / Charts** — `Register.defaultDashboardId` and dashboard queries/mutations
45
+ are not yet wrapped. Backend has dashboard configuration tied to registers and organisations.
46
+ Scope: `Base::Dashboard` model, `Query::Dashboard(s)`, `Builder::Register#set_default_dashboard`.
47
+ Priority: medium needed when scripts need to manage register dashboard configs.
48
+
49
+ - [x] **AI field mutations** `generateAiSummary`, `generateSmartFill`,
50
+ `submitAiSummaryFeedback`, `submitSmartFillFeedback` fully wrapped.
51
+ `Mutation::AiSummary::Generate/SubmitFeedback`, `Mutation::SmartFill::Generate/SubmitFeedback`,
52
+ `Payload::AiSummaryGenerate`, `Payload::OkPayload`, `Base::AiSummaryVersion`.
53
+ `Builder::Page` wired: `generate_ai_summary`, `submit_ai_summary_feedback`,
54
+ `generate_smart_fill`, `submit_smart_fill_feedback`.
55
+ *Done 2026-06-08*
56
+
57
+ - [ ] **AI prompt review workflow** — AiSummary and SmartFill fields store an `instructions`
58
+ field (the AI prompt, template-configured by humans). No audit/review workflow exists.
59
+ The gem can read `field.instructions` on AiSummary/SmartFill instances already.
60
+ What's needed: a way to scan pages/templates for these instructions and surface them
61
+ for review. Possibly: `Query::PagesWithAiFields` + a review report script.
62
+ See `.ai-assistance/code/ecoPortal_architecture/13_ai_infrastructure.md` for context.
63
+ Priority: low/design — the need is real but the right interface is TBD.
64
+
65
+ - [x] **eP Meta AI scaffolding project** — Standalone template repo at
66
+ `C:\ruby_scripts\git\ecoPortal_ai_standards`. Bridge protocol, all scripts
67
+ (lock-acquire, task-read, task-create, setup-mcps, etc.), all skills, conventions,
68
+ integrations, capabilities registry, CLAUDE.md template ({{PLACEHOLDER}} vars),
69
+ ONBOARDING.md (15-min setup guide), `init-project.ts` bootstrap script.
70
+ Push to GitLab to share: `git@gitlab.ecoportal.co.nz:oscar/ecoPortal_ai_standards.git`
71
+ *Done 2026-06-08*
72
+
73
+ - [ ] **Commit unstaged changes** Large set of modified files on `ai_dev_process` branch
74
+ not yet staged or committed. Review and commit once session is fully restored.
75
+
76
+ ## Bridge improvements (from Gemini review 2026-06-04)
77
+
78
+ - [x] **Security: Code must prompt before executing bridge-requested shell commands**
79
+ Rule added to `.ai-assistance/bridge/CLAUDE.md` "Running Code non-interactively" section.
80
+ Code must surface any shell command to the user before running it, even in
81
+ skip-permissions mode. User denial mark task FAILED.
82
+ *Done 2026-06-08*
83
+
84
+ - [x] **Atomic LOCK acquisition** — `scripts/lock-acquire.sh` implemented.
85
+ Uses temp-file + hard-link (atomic on POSIX/NTFS); falls back to bash `noclobber`.
86
+ Reports held-by agent/intent on contention. Auto-detects stale locks by mtime.
87
+ `bridge/CLAUDE.md` updated to reference it as the preferred acquisition method.
88
+ *Done 2026-06-08*
89
+
90
+ - [x] **Stale IN_PROGRESS recovery** — `bridge-init.sh` updated: scans for IN_PROGRESS
91
+ tasks older than 1 hour (via `stat` mtime), reports them in `stale_tasks` + `stale`
92
+ count in STATUS JSON. `bridge/CLAUDE.md` updated with Code's required response:
93
+ report to user, ask to reset to PENDING or mark FAILED.
94
+ *Done 2026-06-08*
95
+
96
+ - [x] **`task-read.ts` script** — `scripts/task-read.ts` implemented.
97
+ Parses all sections (title, status, created, from, to, context, request, expected,
98
+ result, notes) from inbox/outbox/archive files. Searches all bridge dirs automatically.
99
+ Output: structured JSON. Saves ~200 tokens per task read vs raw Markdown.
100
+ *Done 2026-06-08*
101
+
102
+ - [x] **Archive pruning convention** — Documented in `bridge/CLAUDE.md` "Archive pruning"
103
+ section: keep last 90 days or last 50 task pairs; git history is the audit trail;
104
+ prune manually when folder gets unwieldy.
105
+ *Done 2026-06-08*
106
+
107
+ ## File upload
108
+
109
+ - [x] **BUG — `FileUpload::Client` auth mechanism (confirmed live 2026-07-26, fixed same day).**
110
+ Implemented in commit `9f769cc` (2026-06-08) as a port of `ecoportal-api-v2`'s
111
+ `S3::Data`/`S3::Upload`/`S3::Files` — shipped in CHANGELOG but with **zero test coverage
112
+ ever** (no specs, no VCR, no manual test script). Live-verified via `training` repo →
113
+ `mini/automated-tests/tests/pages/file_upload_test.rb`: `Query::FileUploadSignature`
114
+ (step 1, GraphQL presign) succeeds, but the REST registration step
115
+ (`POST /api/v2/<org_id>/s3/files`, step 3) **404s**.
116
+ **Root cause:** `ecoportal-api-v2`'s REST S3 endpoints authenticate via
117
+ `X-ECOPORTAL-API-KEY` header (`Common::Content::Client#base_request`), but the ported
118
+ `FileUpload::Client` sends `Authorization: Bearer <oauth_token>` instead (the same token
119
+ used for GraphQL) — wrong auth mechanism for those specific REST endpoints.
120
+ **Fix (branch `fix/file-upload-api-key-auth`):** added `api_key:` to
121
+ `Ecoportal::API::GraphQL.new` (threaded to `HttpClient`, independent of the GraphQL
122
+ endpoint's own email/pass OAuth bearer token), exposed `HttpClient#api_key` publicly, and
123
+ changed `FileUpload::Client#upload_get`/`#upload_post` to send `X-ECOPORTAL-API-KEY`
124
+ instead of `Authorization: Bearer`, raising a clear error if no `api_key:` was configured.
125
+ 18 new specs added (`graphql_spec.rb`, `http_client_spec.rb`, `file_upload_signature_spec.rb`,
126
+ `file_upload/client_spec.rb` — full 4-step `#upload` orchestration + auth-header assertions).
127
+ **Still NOT live-verified** — no credentials were available in the environment this was
128
+ fixed in; run `training/mini/automated-tests -only pages/file_upload` (with a real
129
+ `api_key:` wired into that harness's `graphql` session helper — check where it builds
130
+ `Ecoportal::API::GraphQL.new` and add `api_key:` there too) before trusting this in
131
+ production.
132
+ **Still open / NOT covered by this fix:**
133
+ - The S3 key path is built by string concatenation (`upload_prefix + filename`) vs v2's
134
+ slash-joined `"#{user_tmpdir}/#{file_basename}"`.
135
+ - The multipart POST hardcodes `x-amz-server-side-encryption: AES256` instead of reading
136
+ the value v2 gets from the presigned credentials response.
137
+ - The hand-rolled multipart builder should probably be replaced with `Net::HTTP#set_form`
138
+ (what v2 uses, more robust than hand-built boundaries).
139
+ - No mutation exists anywhere in this gem to set `FileContainer#tags` — confirm whether
140
+ that's even possible via GraphQL before promising it in any customer-facing demo.
141
+ - **Threading/multi-file:** `ecoportal-api-v2` has a real, previously-uncovered threaded
142
+ batch-upload path (`S3::Files::BatchUpload` + `Concerns::Threadable`, `threads:` param,
143
+ per-file error isolation) — now specced (`ecoportal-api-v2` branch, 3 new specs).
144
+ Assessment: do NOT port this to `FileUpload::Client` yet — it only handles one file per
145
+ call today, and Oscar has already explicitly deferred a bulk/multi-file DX shortcut here
146
+ in favor of a future backend async batch-upload feature (out of scope for this gem).
147
+ Revisit only once the auth fix is live-verified as a working single-file baseline AND
148
+ bulk latency is confirmed to actually matter in practice.
149
+ Priority: was **High** (blocked `ep-api-collections`' Files Upload group and any real
150
+ usage of `#file_upload`) — auth mechanism now fixed pending live verification; the Files
151
+ Upload collection group should stay un-built until that live verification passes.
152
+
153
+ - [ ] **File upload — data field wiring (original scope, still valid once the bug above is fixed)**
154
+ Support uploading files to attach to `File` and `ImageGallery` data fields (and
155
+ potentially Action file attachments at a later stage). Distinct from `attach` (which
156
+ links existing resources). Scope:
157
+ - Create `Input::FileAttachment` to carry the resulting file container ID into mutations
158
+ - Wire into data field update inputs (Phase E concern for fields, sooner for Actions)
159
+ Priority: Medium — needed before data field updates can be fully functional.
160
+ Note: Actions file attachment may be needed sooner — track separately if it becomes urgent.
161
+
162
+ ## Completed
163
+
164
+ - [x] **Gemini design review of bridge architecture** — Done 2026-06-04. Response in
165
+ `.ai-assistance/bridge/context/gemini-review-response.md`.
166
+ - [x] **Regenerate GitLab PAT** — New token generated, April 2027 expiry, rotation enabled.
167
+ Updated in `.env` and documented in `integrations/gitlab-mcp.md`.
168
+ - [x] **Rename `.claude/` to `.ai-assistance/`** — Done 2026-06-04. All references updated
169
+ across scripts, CLAUDE.md, gitignore, and capabilities docs.
170
+ - [x] **MCP setup script** — `setup-mcps.ts` + tests written. Teammates run once per machine.
@@ -1,48 +1,48 @@
1
- # SKILL: AI Instructions Generator, Reviewer & Updater
2
-
3
- **Purpose:** Keep CLAUDE.md, skill files, and conventions accurate, tidy, and placed correctly as the project evolves.
4
-
5
- ---
6
-
7
- ## When to Use
8
-
9
- - A developer makes an observation that reveals a gap, mistake, or new convention.
10
- - A new pattern emerges in the code that future AI agents should know about.
11
- - A skill needs to be created, updated, or split.
12
- - CLAUDE.md needs to reflect a structural change to the repo.
13
-
14
- ---
15
-
16
- ## Decision: Practice/Convention vs. CLAUDE.md Instruction vs. Skill
17
-
18
- When an observation is made, scope it:
19
-
20
- | Type | Where it goes |
21
- |------|--------------|
22
- | One-off note or context | Inline comment in the relevant `.ai-assistance/code/*.md` doc |
23
- | Convention (how we do things here) | `CLAUDE.md` → Conventions section |
24
- | Always-do behaviour for AI agents | `CLAUDE.md` → Before Starting Any Task, or a new section |
25
- | Reusable, invocable capability | New or updated `SKILL.md` in `.ai-assistance/skills/<skill-name>/` |
26
-
27
- ---
28
-
29
- ## File Placement Rules
30
-
31
- - **CLAUDE.md** lives at repo root — one file, always.
32
- - **Skills** live at `.ai-assistance/skills/<skill-name>/SKILL.md`.
33
- - Additional assets (scripts, prompts) live alongside the SKILL.md in the same folder.
34
- - **Code specs** live at `.ai-assistance/code/` (see `code-specs` skill).
35
- - **Project files** live at `.ai-assistance/projects/<project-name>/` (see `project-cycle` skill).
36
- - **Refactoring logs** live at `.ai-assistance/code/refactoring/` (see `refactor` skill).
37
-
38
- **Never scatter instruction files in code directories.** All AI tooling lives under `.ai-assistance/`.
39
-
40
- ---
41
-
42
- ## Workflow
43
-
44
- 1. Identify the type of observation (see table above).
45
- 2. Locate the correct file. Create it if it doesn't exist.
46
- 3. Make the minimal change — don't rewrite documents unnecessarily.
47
- 4. Update the skill index table in CLAUDE.md if a new skill was added.
48
- 5. Confirm with the developer if the change affects an existing convention that other developers rely on.
1
+ # SKILL: AI Instructions Generator, Reviewer & Updater
2
+
3
+ **Purpose:** Keep CLAUDE.md, skill files, and conventions accurate, tidy, and placed correctly as the project evolves.
4
+
5
+ ---
6
+
7
+ ## When to Use
8
+
9
+ - A developer makes an observation that reveals a gap, mistake, or new convention.
10
+ - A new pattern emerges in the code that future AI agents should know about.
11
+ - A skill needs to be created, updated, or split.
12
+ - CLAUDE.md needs to reflect a structural change to the repo.
13
+
14
+ ---
15
+
16
+ ## Decision: Practice/Convention vs. CLAUDE.md Instruction vs. Skill
17
+
18
+ When an observation is made, scope it:
19
+
20
+ | Type | Where it goes |
21
+ |------|--------------|
22
+ | One-off note or context | Inline comment in the relevant `.ai-assistance/code/*.md` doc |
23
+ | Convention (how we do things here) | `CLAUDE.md` → Conventions section |
24
+ | Always-do behaviour for AI agents | `CLAUDE.md` → Before Starting Any Task, or a new section |
25
+ | Reusable, invocable capability | New or updated `SKILL.md` in `.ai-assistance/skills/<skill-name>/` |
26
+
27
+ ---
28
+
29
+ ## File Placement Rules
30
+
31
+ - **CLAUDE.md** lives at repo root — one file, always.
32
+ - **Skills** live at `.ai-assistance/skills/<skill-name>/SKILL.md`.
33
+ - Additional assets (scripts, prompts) live alongside the SKILL.md in the same folder.
34
+ - **Code specs** live at `.ai-assistance/code/` (see `code-specs` skill).
35
+ - **Project files** live at `.ai-assistance/projects/<project-name>/` (see `project-cycle` skill).
36
+ - **Refactoring logs** live at `.ai-assistance/code/refactoring/` (see `refactor` skill).
37
+
38
+ **Never scatter instruction files in code directories.** All AI tooling lives under `.ai-assistance/`.
39
+
40
+ ---
41
+
42
+ ## Workflow
43
+
44
+ 1. Identify the type of observation (see table above).
45
+ 2. Locate the correct file. Create it if it doesn't exist.
46
+ 3. Make the minimal change — don't rewrite documents unnecessarily.
47
+ 4. Update the skill index table in CLAUDE.md if a new skill was added.
48
+ 5. Confirm with the developer if the change affects an existing convention that other developers rely on.