Skip to content

feat(roles): five coding-agent personas (D3) - #37

Closed
flg77 wants to merge 1 commit into
feat/stub-coding-skillsfrom
feat/coding-agent-personas
Closed

feat(roles): five coding-agent personas (D3)#37
flg77 wants to merge 1 commit into
feat/stub-coding-skillsfrom
feat/coding-agent-personas

Conversation

@flg77

@flg77 flg77 commented May 7, 2026

Copy link
Copy Markdown
Owner

Stacked on PR #36 (D4 stub skills). Lands the five specialist personas the runnable demo expects: architect, implementer, reviewer, tester, dependency_auditor. 32 tests pin schema invariants per persona; 131 passed across related modules.

Specialist personas for cluster fan-out — each is a narrowed
coding_agent with distinct system prompt, default skill set,
estimator config, and eval rubric.  Designs from
docs/CODING_AGENT_SUBROLES.md.

New role directories under roles/:
* coding_agent_architect — single-instance interface designer.
  Estimator: fixed count=1.  Default skill: code_review.
  Pattern B (knowledge-share fan-in) — publishes draft_interface.
* coding_agent_implementer — multi-instance code writer.
  Estimator: heuristic base=1, per_n_tokens=1500, cap=4 +
  difficulty bumps for 'concurrency' and 'refactor'.  Default
  skill: code_generation.
* coding_agent_reviewer — single-instance verdict author.
  Estimator: fixed count=1.  Default skills: code_review +
  security_scan.  Carries security_audit receptor.
* coding_agent_tester — multi-instance test author + runner.
  Estimator: heuristic base=1, per_n_tokens=3000, cap=3 +
  security difficulty bump.  Default skills: test_generation,
  test_execution.
* coding_agent_dependency — single-instance CVE / license auditor.
  Estimator: fixed count=1.  Default skills: dependency_audit,
  security_scan.  Carries security_audit receptor.

Each persona carries:
* role.md — operator-facing markdown source (lints clean).
* role.yaml — canonical compiled YAML.
* system_prompt.md — distinct prompt that includes the persona's
  cancellation behaviour.
* eval_rubric.yaml — weights sum to 1.0, security ≥ 10% (mirrors
  the schema invariant pinned for the bare coding_agent).

Tests — tests/test_coding_agent_personas.py (32 cases — 5 personas
× 6 invariants each + 2 cross-persona):
* role.md lints clean (5).
* role.yaml loads via RoleLoader with the right estimator
  block + max_parallel_tasks (5).
* default_skills ⊆ allowed_skills (5).
* default_skills resolve in the live skill registry — D4
  prerequisite (5).
* Rubric weights sum to 1.0 (5).
* Rubric security weight ≥ 10% (5).
* Reviewer + dependency_auditor carry security_audit receptor (1).

131 passed across the related test sweep.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@flg77
flg77 deleted the branch feat/stub-coding-skills May 7, 2026 19:14
@flg77 flg77 closed this May 7, 2026
flg77 added a commit that referenced this pull request May 7, 2026
* feat(skills): six stub coding-cluster skills (D4)

The five coding-agent personas (D3 follow-up) reference six skills
that did not exist on disk: code_review, code_generation,
test_generation, test_execution, security_scan, dependency_audit.

Each ships:
* skills/<name>/skill.yaml — LOW-risk manifest, adapter_class
  StubCodingSkill, domain_id software_engineering or security_audit
  (per the receptor model in docs/SUBAGENT_COMMUNICATION.md).
* skills/<name>/adapter.py — pass-through StubCodingSkill that
  round-trips the LLM-supplied text and tags it with the skill_id
  for audit attribution.

The skills are governance-only stubs.  The LLM still does the
actual work via its natural-language output; the skill registry
contributes:
* Cat-A A-017 enforcement (skill ceiling + allow-list).
* Audit anchor on TASK_COMPLETE.invocations.
* skill_in_use column on the cluster panel (PR #29).

Replacing each adapter with a real linter / static-analysis /
pytest backend is a separate hardening track.

Tests — tests/test_stub_skills.py (10 cases):
* All six manifests load via SkillRegistry.load_from.
* All six are LOW risk (default MEDIUM ceiling accepts them).
* Adapter round-trips input text per skill_id (parametrised).
* Per-skill module isolation — each adapter resolves to its own
  manifest's skill_id.
* Domain-id alignment matches the receptor-filter expectations.

110 passed across PR-26..30 + new module on the local sweep.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(roles): five coding-agent personas (D3)

Specialist personas for cluster fan-out — each is a narrowed
coding_agent with distinct system prompt, default skill set,
estimator config, and eval rubric.  Designs from
docs/CODING_AGENT_SUBROLES.md.

New role directories under roles/:
* coding_agent_architect — single-instance interface designer.
  Estimator: fixed count=1.  Default skill: code_review.
  Pattern B (knowledge-share fan-in) — publishes draft_interface.
* coding_agent_implementer — multi-instance code writer.
  Estimator: heuristic base=1, per_n_tokens=1500, cap=4 +
  difficulty bumps for 'concurrency' and 'refactor'.  Default
  skill: code_generation.
* coding_agent_reviewer — single-instance verdict author.
  Estimator: fixed count=1.  Default skills: code_review +
  security_scan.  Carries security_audit receptor.
* coding_agent_tester — multi-instance test author + runner.
  Estimator: heuristic base=1, per_n_tokens=3000, cap=3 +
  security difficulty bump.  Default skills: test_generation,
  test_execution.
* coding_agent_dependency — single-instance CVE / license auditor.
  Estimator: fixed count=1.  Default skills: dependency_audit,
  security_scan.  Carries security_audit receptor.

Each persona carries:
* role.md — operator-facing markdown source (lints clean).
* role.yaml — canonical compiled YAML.
* system_prompt.md — distinct prompt that includes the persona's
  cancellation behaviour.
* eval_rubric.yaml — weights sum to 1.0, security ≥ 10% (mirrors
  the schema invariant pinned for the bare coding_agent).

Tests — tests/test_coding_agent_personas.py (32 cases — 5 personas
× 6 invariants each + 2 cross-persona):
* role.md lints clean (5).
* role.yaml loads via RoleLoader with the right estimator
  block + max_parallel_tasks (5).
* default_skills ⊆ allowed_skills (5).
* default_skills resolve in the live skill registry — D4
  prerequisite (5).
* Rubric weights sum to 1.0 (5).
* Rubric security weight ≥ 10% (5).
* Reviewer + dependency_auditor carry security_audit receptor (1).

131 passed across the related test sweep.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
flg77 added a commit that referenced this pull request May 7, 2026
…reopened) (#40)

* feat(arbiter): wire role_resolver + skill_resolver into PlanExecutor (D1)

PR #26-#30 delivered the wire protocol + estimator + TUI panel + slash
commands for sub-agent clustering, but the arbiter agent itself did
NOT pass role_resolver / skill_resolver into PlanExecutor. Without
those callbacks, every PLAN step fell back to legacy single-agent
dispatch — the cluster fan-out path was unreachable in production.

acc/agent.py:
* New _build_cluster_resolvers() helper returns (role_resolver,
  skill_resolver) for the arbiter's PlanExecutor.
* role_resolver: RoleLoader against $ACC_ROLES_ROOT (or ./roles).
  Swallows + logs exceptions so a malformed role.yaml never crashes
  dispatch — executor falls back to single-agent in that case.
* skill_resolver: intersection of role.allowed_skills and the live
  SkillRegistry.list_skill_ids() — operator-visible list, not the
  registry total. A whitelisted-but-not-loaded skill cannot leak to
  the cluster panel's skill_in_use column.
* Falls back to role.allowed_skills directly when the registry isn't
  yet initialised. The eventual A-017 invocation gate still enforces
  real-skill-only at dispatch time.

Tests — tests/test_arbiter_cluster_dispatch.py (6 cases):
* role_resolver returns RoleDefinitionConfig for a known role.
* role_resolver returns None for unknown role (executor falls back).
* skill_resolver intersection — non-allowed registry skills do not leak.
* skill_resolver fail-closed when role has no allowed_skills.
* skill_resolver falls back to role.allowed_skills when registry None.
* role_resolver swallows loader exceptions (does not raise).

88 passed across PR-26..30 + new module on the local sweep.

Foundation for the persona+skill-cluster showcase tracked in
the approved plan.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(cli): plan submit accepts JSON and YAML (D2)

acc-cli plan submit previously called json.loads() directly, which
rejected the YAML scenario plans documented under
examples/coding_split_skills/. YAML is the natural pair for the role.md
authoring format (PR #28); plan files should not require an
extra json-conversion step.

acc/cli/plan_cmd.py:
* New _parse_plan_text(raw, path_hint) helper.
* Files ending .yaml / .yml parse via PyYAML; YAML errors are loud
  (a yaml-extension file should always be valid YAML).
* Other paths attempt JSON first and fall back to YAML on
  JSONDecodeError so stdin can carry either dialect.
* PyYAML is already a project dep (used everywhere else in acc/);
  no new requirement.

7 new tests in tests/test_cli_plan_yaml.py:
* JSON plan parses (back-compat).
* YAML plan parses (.yaml + .yml extensions).
* Broken .yaml fails loudly with 'invalid YAML' in stderr.
* Stdin-style YAML body parses via JSON-fallback.
* Malformed input returns None with 'invalid JSON' diagnostic.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(skills): six stub coding-cluster skills (D4)

The five coding-agent personas (D3 follow-up) reference six skills
that did not exist on disk: code_review, code_generation,
test_generation, test_execution, security_scan, dependency_audit.

Each ships:
* skills/<name>/skill.yaml — LOW-risk manifest, adapter_class
  StubCodingSkill, domain_id software_engineering or security_audit
  (per the receptor model in docs/SUBAGENT_COMMUNICATION.md).
* skills/<name>/adapter.py — pass-through StubCodingSkill that
  round-trips the LLM-supplied text and tags it with the skill_id
  for audit attribution.

The skills are governance-only stubs.  The LLM still does the
actual work via its natural-language output; the skill registry
contributes:
* Cat-A A-017 enforcement (skill ceiling + allow-list).
* Audit anchor on TASK_COMPLETE.invocations.
* skill_in_use column on the cluster panel (PR #29).

Replacing each adapter with a real linter / static-analysis /
pytest backend is a separate hardening track.

Tests — tests/test_stub_skills.py (10 cases):
* All six manifests load via SkillRegistry.load_from.
* All six are LOW risk (default MEDIUM ceiling accepts them).
* Adapter round-trips input text per skill_id (parametrised).
* Per-skill module isolation — each adapter resolves to its own
  manifest's skill_id.
* Domain-id alignment matches the receptor-filter expectations.

110 passed across PR-26..30 + new module on the local sweep.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(roles): five coding-agent personas (D3)

Specialist personas for cluster fan-out — each is a narrowed
coding_agent with distinct system prompt, default skill set,
estimator config, and eval rubric.  Designs from
docs/CODING_AGENT_SUBROLES.md.

New role directories under roles/:
* coding_agent_architect — single-instance interface designer.
  Estimator: fixed count=1.  Default skill: code_review.
  Pattern B (knowledge-share fan-in) — publishes draft_interface.
* coding_agent_implementer — multi-instance code writer.
  Estimator: heuristic base=1, per_n_tokens=1500, cap=4 +
  difficulty bumps for 'concurrency' and 'refactor'.  Default
  skill: code_generation.
* coding_agent_reviewer — single-instance verdict author.
  Estimator: fixed count=1.  Default skills: code_review +
  security_scan.  Carries security_audit receptor.
* coding_agent_tester — multi-instance test author + runner.
  Estimator: heuristic base=1, per_n_tokens=3000, cap=3 +
  security difficulty bump.  Default skills: test_generation,
  test_execution.
* coding_agent_dependency — single-instance CVE / license auditor.
  Estimator: fixed count=1.  Default skills: dependency_audit,
  security_scan.  Carries security_audit receptor.

Each persona carries:
* role.md — operator-facing markdown source (lints clean).
* role.yaml — canonical compiled YAML.
* system_prompt.md — distinct prompt that includes the persona's
  cancellation behaviour.
* eval_rubric.yaml — weights sum to 1.0, security ≥ 10% (mirrors
  the schema invariant pinned for the bare coding_agent).

Tests — tests/test_coding_agent_personas.py (32 cases — 5 personas
× 6 invariants each + 2 cross-persona):
* role.md lints clean (5).
* role.yaml loads via RoleLoader with the right estimator
  block + max_parallel_tasks (5).
* default_skills ⊆ allowed_skills (5).
* default_skills resolve in the live skill registry — D4
  prerequisite (5).
* Rubric weights sum to 1.0 (5).
* Rubric security weight ≥ 10% (5).
* Reviewer + dependency_auditor carry security_audit receptor (1).

131 passed across the related test sweep.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(example+docs): runnable coding-split-skills showcase + doc enhancements (D5+D6)

Stacked atop PRs #34-#37 — combines the arbiter resolver wiring,
CLI YAML support, stub skills, and personas into a fully runnable
end-to-end scenario.

examples/coding_split_skills/ (the deliverable):
* .env.example — every operator-configurable variable in one
  commented file.  Three LLM-backend options preconfigured
  (Anthropic, Ollama, OpenShift AI vLLM-compat).
* run.sh — one-command runner.  Sources .env, lints every
  persona's role.md, brings the stack up via acc-deploy.sh,
  submits the plan via acc-cli plan submit.
* verify.sh — programmatic post-run check.  Subscribes to
  acc.{cid}.> for ACC_VERIFY_DURATION_S seconds, parses
  cluster_id values out of the bus, exits 0 when ≥
  ACC_VERIFY_MIN_CLUSTERS distinct clusters were observed.
  CI-friendly.
* clean.sh — teardown + scratchpad eviction.
* plan.json — JSON copy of plan.yaml for environments without
  YAML support (D2 makes both work via acc-cli plan submit).
* README.md — rewritten with the live "one command" flow and
  troubleshooting matrix.

Docs landed alongside the runnable example:
* docs/IMPLEMENTATION_subagent_clustering.md — wire-protocol +
  module reference for PRs #26-#30 (was pending commit).
* docs/SUBAGENT_COMMUNICATION.md — Patterns A-E catalogue.
* docs/INDEX_subagent_clustering.md — cross-reference matrix.
* docs/ROADMAP_subagent_clustering.md — short / medium / long
  forecasts; "won't do" list.
* docs/CODING_AGENT_SUBROLES.md — caveat dropped (the personas
  are LIVE as of PR #37); rubric summary table + cancellation
  behaviour summary appended; "How the showcase actually runs"
  section linked to examples/coding_split_skills/.
* docs/DEMO_TUI_subagent_clustering.md — Phase 1.5 (env prep) +
  Phase 4.5 (verify.sh) added; Phase 3 substitutes the synthetic
  acc-cli plan submit with the actual run.sh; Phase 5 lists the
  five personas as concrete artefacts; Known-gaps list updated
  to reflect the merged state.

179 passed across the related test sweep on this branch (combined
PR-26..30 + D1 + D2 + D3 + D4 work).

End-to-end usage:
    cp examples/coding_split_skills/.env.example examples/coding_split_skills/.env
    $EDITOR examples/coding_split_skills/.env       # set LLM creds
    ./examples/coding_split_skills/run.sh
    acc-tui                                          # press 7
    ./examples/coding_split_skills/verify.sh         # exit 0 = ok
    ./examples/coding_split_skills/clean.sh          # tear down

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
flg77 added a commit that referenced this pull request May 31, 2026
…tor-repurpose, compliance-multikind, sub-collective-editor (2026-05-31)

Five OpenSpec proposals authored during the 2026-05-30 / 2026-05-31
brainstorm waves. All five carry the same shape: phase 1 purely
additive, later phases gated on operator review or sibling proposals.

1. `20260530-acc-dreaming-agent` — out-of-band memory consolidation
   role (analogue of Anthropic Dreaming, May 2026). Phase 1 observation-
   only: M5 (centroid recompute) + M8 (poisoning detection) + M10
   (markdown export) + M11 (convergent-workflow) + M12 (preference
   extraction). Six lifted safety invariants from Anthropic's design.
   Brainstorm: `Notes/.../ACC-Dreaming/`.

2. `20260531-acc-role-package-format` — versioned signed `.accpkg`
   packages + community hub. Phase 1 format spec + reference CLI.
   Maturity ladder (alpha/beta/stable/hardened); cosign+SPIFFE trust;
   edge specialist mode after Phase 3 substrate slim. Brainstorm:
   `Notes/.../ACC-Role-Format/`.

3. `20260531-orchestrator-repurpose-skills-mcp-specialist` — closes
   followup #37. Orchestrator stops competing with Assistant on routing
   and starts answering "what's available?" — owns the collective's
   capability catalog. Phase 1 catalog + capability.query subject
   (read-only). Brainstorm: `Notes/.../ACC-Orchestrator-Repurpose/`.

4. `20260531-compliance-pane-multikind-consolidation` — closes followup
   #39. Compliance pane now carries six oversight kinds undifferentiated;
   Phase 1 adds a `kind` discriminator on `OversightItem` + three sub-
   tabs (Approvals / Audit / Diagnostics). Brainstorm:
   `Notes/.../ACC-Compliance-Pane-Multikind/`.

5. `20260531-managed-sub-collectives-typed-editor` — closes followup
   #42. AoA-P3a's `managed_sub_collectives` dict gains a typed editor
   sub-tab on the Ecosystem Agentset surface (Roster · Sub-collectives
   · Raw YAML). Phase 1 local roles only; Phase 4 rides role-package
   marketplace; Phase 5 rides orchestrator's CapabilityIndex.
   Brainstorm: `Notes/.../ACC-Subcollective-Editor/`.

Cross-proposal dependencies (each implementable in isolation; ride
deps checked at gate, not in code):

- Orchestrator's RECOMMEND_* kind  → Compliance Multi-Kind registers it
- Dreamer's DREAM_REPORT kind      → Compliance Multi-Kind registers it
- Sub-Collective Editor Phase 4    → Role-Package Format Phase 4
- Sub-Collective Editor Phase 5    → Orchestrator Repurpose Phase 1
- Orchestrator Phase 5             → Role-Package Format Phase 4
- Orchestrator Phase 6             → Dreamer Phase 5 (M9)

Each proposal has a matching brainstorm folder in the Obsidian vault
with the operational reasoning (annotated bibliography, open questions,
operator-facing UX sketches) preserved.

Tracker: followup-acc.md — #37, #39, #42 marked CLOSED with proposal
links; #38 documented (no fix), #40 gated on A2A Phase 3, #41 doc-sync
already applied.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
flg77 added a commit that referenced this pull request May 31, 2026
…3.42) (#8)

Closes followup #37 IN CODE (not just a proposal).

OpenSpec `20260531-orchestrator-repurpose-skills-mcp-specialist` Phase 1
ships the read-only catalog + NATS request/reply query subject.  Phases
2–7 deferred behind operator-review gates (recommendation markers, gap
analyser, [ROUTE:...] deprecation, marketplace mirror, dreamer M9 ride,
final removal).

Phase 1 is **purely additive**: existing routing paths
(orchestrator's [ROUTE:role:reason] AND Assistant's [PROPOSE_ROUTE]) both
keep working unchanged.  Future phases retire the legacy marker.

What landed:

1. `acc/capability_index.py` — `CapabilityIndex` class.  Scans
   `roles/*/role.yaml` + `mcps/*/mcp.yaml` + (optional) SkillRegistry at
   boot; deterministic query path with kind/name/domain/task_type/limit
   filters; revision counter increments on rebuild; SIGHUP-reload on
   non-Windows.  Pydantic v2 models with `extra="forbid"` reject
   malformed wire requests.  Empty roots are non-fatal (slim-edge
   deploys).

2. `acc/signals.py` — `subject_capability_query(cid)` +
   `subject_capability_recommend(cid)` (the recommend subject is
   declared in Phase 1 so consumers can subscribe early; no producer
   emits until Phase 2).

3. `acc/agent.py` — two coupled hooks:
   * `_maybe_build_capability_index()` — boot-time, role-gated, builds
     the index when `self.config.agent.role == "orchestrator"`; logs
     `capability_index: built at boot revision=1`.
   * `_handle_capability_query` (inside `_task_loop`) — NATS
     request/reply handler; unpacks msgpack, validates via Pydantic,
     queries index, publishes reply on `msg.reply` inbox.

4. `roles/orchestrator/role.yaml` — bumped to `v3.0.0-beta1`.  Purpose
   rewritten (Skills & MCP specialist).  New allowed_actions:
   `capability_query`, `capability_reply`.  Phase 1 RETAINS
   `can_route: true` for backward compat; Phase 4 deprecates with
   warning + auto-translate; Phase 3 flips it to false once the gap
   analyser ships.  Seed_context narrative explains the repurpose.

5. `tests/test_capability_index.py` — 16 tests covering scan
   correctness, query filters, Pydantic strictness, revision counter,
   optional SkillRegistry integration, empty-roots edge case, and the
   140-char summary truncation.

Tests:
- `pytest tests/test_capability_index.py` — 16 passed.
- `pytest -k "orchestrator or capability or role_def or signals"` —
  175 passed, 3 skipped, 0 failed.
- Full sweep `pytest tests/ --ignore=tests/container -x` —
  **2435 passed, 38 skipped, 0 failed**.

Downstream proposals unblocked (when their phases land):
- Sub-collective editor Phase 5 — "Suggest skills/MCPs" button queries
  capability.query.
- Dreamer Phase 6 — M9 distilled-skill ingest writes back to the
  catalog.
- Role-package format Phase 5 — marketplace mirror surfaces here.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
flg77 added a commit that referenced this pull request Jun 8, 2026
Phase F.1 + Stage 2.5: A2A federation cache + Podman Desktop scope
flg77 added a commit that referenced this pull request Jun 29, 2026
…cryptography (#141)

Resolves the Python (pip) Dependabot alerts on flg77/acc-spearhead. Most were a
stale uv.lock (last generated 2026-06-14) whose pins lagged the already-permissive
pyproject constraints; one needed a constraint widening.

Lockfile refresh (constraints already allowed the fix — `uv lock --upgrade-package`):
  aiohttp   3.14.0 → 3.14.1   (#15-22, 8 alerts)
  pyjwt     2.12.1 → 2.13.0   (#9-13, 5 alerts)
  starlette 1.0.1  → 1.3.1    (#24-27, 4 alerts; transitive via fastapi)
  msgpack   1.1.2  → 1.2.1    (#37, high)
  joserfc   1.6.5  → 1.7.2    (#39; transitive via authlib)

Constraint widening (fix was outside the pin):
  cryptography 46.0.7 → 48.0.1 (#14/#23, two HIGH) — pyproject `<47`→`>=48.0.1,<49`.
  The Ed25519 arbiter sign/verify API is stable across 46→48; operator "pin and
  bump" one major at a time.

The lock also catches up on the speech/turbovec optional-deps added since 06-14
(faster-whisper/piper-tts/ctranslate2/onnxruntime/av/turbovec) — no security
content, just lock/pyproject reconciliation. No downgrades.

Not fixed here (separate handling):
  transformers (#1) — vulnerable `Trainer` not in our execution path; ST<5.0 blocks
    the 5.0.0rc3 fix → dismissed on GitHub with that reason (intent already in
    pyproject).
  torch (#7, low) — no patched release exists → dismissed "no fix available".
  npm console-plugin (7 alerts) — need npm/node (absent here) → fleet hand-off.

Verified with the bumped libs installed: signatures/spiffe 153 ✓, a2a/messenger/
slack/webgui/redis 168 ✓ (321 total, 0 failures).

Co-authored-by: flg <flg@acc1.ic3net.internal>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant