Compare commits

...

6 Commits

Author SHA1 Message Date
e4b39c4a9e refactor: update work item statuses and sprint planning details for PDIAP-15836 and PDIAP-12284 2026-05-05 16:09:48 -06:00
2a234701c5 Update work items and daily logs for project fidelity
- Updated work items with new statuses, notes, and dependencies:
  - `PDIAP-15838` moved to Done, draft PR remains unmerged.
  - `PDIAP-15836` status updated to backlog-ready, sequenced after `PDIAP-15838`.
  - `PDIAP-12284` reopened for UIKit removal, dependency for `PDIAP-15836`.
  - Added new backlog items: `PDIAP-11961`, `PDIAP-11962`, `PDIAP-11562`, `PDIAP-12226`, `PDIAP-12227`, `PDIAP-12228`.
- Completed `PDIAP-16167`, documented findings in Confluence.
- Created daily log for 2026-05-05 summarizing work item updates and backlog triage.
- Added diagnostic script for workspace analysis.
2026-05-05 15:54:45 -06:00
63e784cc97 refactor: update agent sync behavior, improve freshness detection patterns, and add diagnostic troubleshooting script 2026-05-05 07:43:45 -06:00
f685ac37dd feat: add shared agent skills index and integrate SwiftUI skills for Antigravity compatibility 2026-05-04 11:06:49 -06:00
7129a7dc7e chore: remove compatibility field from various agent rules for consistency 2026-05-04 10:04:07 -06:00
ff4ed6a759 feat: refactor work item file retrieval to use Python script for improved error handling and readability 2026-05-04 09:45:28 -06:00
51 changed files with 846 additions and 256 deletions

View File

@@ -1,7 +1,6 @@
---
name: ai-prompt-engineering
description: Create self-contained prompts for another AI assistant that lacks access to this workspace memory.
compatibility: opencode
trigger: always_on
glob: ""
---
@@ -25,4 +24,3 @@ Use this skill when the user wants a prompt for another AI assistant, coding age
- Prefer clear sections over long prose.
- Include work-item ID and title when relevant.
- Make assumptions explicit.

View File

@@ -1,7 +1,6 @@
---
name: copilot-prompt-engineering
description: Create high-quality prompts for GitHub Copilot or another AI running on the Fidelity development machine, using this workspace's context without assuming the target AI has access to it.
compatibility: opencode
trigger: always_on
glob: ""
---

View File

@@ -1,7 +1,6 @@
---
name: ios-swift-answering
description: Answer Swift, SwiftUI, and iOS programming questions using current Apple guidance while adapting recommendations to Fidelity/XFlow project constraints.
compatibility: opencode
trigger: always_on
glob: ""
---

View File

@@ -1,7 +1,6 @@
---
name: ios-testing-strategy
description: Recommend iOS testing approaches for Swift, SwiftUI, XFlow, Fid4, and REST migration work while respecting existing XCTest/Swift Testing/project constraints.
compatibility: opencode
trigger: always_on
glob: ""
---

View File

@@ -1,7 +1,6 @@
---
name: professional-communication
description: Rewrite rough technical notes into clear, concise, stakeholder-ready professional English while preserving scope and technical meaning.
compatibility: opencode
trigger: always_on
glob: ""
---
@@ -23,4 +22,3 @@ Use this skill for manager updates, stakeholder messages, translations, issue cl
- Write natural professional US English.
- Keep messages concise enough for workplace chat unless the user asks for a longer document.
- Do not invent facts, evidence, or commitments.

View File

@@ -1,7 +1,6 @@
---
name: status-reporting
description: Generate work-item-aware standups and status summaries from current workspace memory, recent logs, and communication evidence.
compatibility: opencode
trigger: always_on
glob: ""
---
@@ -24,4 +23,3 @@ Use this skill for standups, daily scrum updates, end-of-day summaries, and shor
- Keep the report concise and ready to send.
- Do not mention internal evidence sources unless the user asks.
- Use `Blockers: None` only when no blocker is visible in current memory.

View File

@@ -1,7 +1,6 @@
---
name: swiftui-xflow-review
description: Review or reason about SwiftUI code in XFlow/Fidelity contexts, especially lifecycle, modal presentation, navigation, backend-driven UI, and UIKit bridge removal.
compatibility: opencode
trigger: always_on
glob: ""
---

View File

@@ -1,7 +1,6 @@
---
name: workspace-memory-curation
description: Maintain file-based operational memory by deciding what to log, promote, correct, or route into tool behavior across reusable AI workspaces.
compatibility: opencode
trigger: always_on
glob: ""
---
@@ -24,4 +23,3 @@ Use this skill when new information may change workspace memory, project state,
- Report updated files and the memory change.
- Preserve uncertainty when confidence is mixed.
- Do not promote tool failures, sync noise, or generic chat chatter as project facts.

30
.agents/skills/index.md Normal file
View File

@@ -0,0 +1,30 @@
# Shared Agent Skills Index
Skills available through the shared `.agents/` surface for Antigravity-compatible workflow views and other tools that read the Agent Skills open format.
---
## Generic Skills
- [Workspace Memory Curation](workspace-memory-curation/SKILL.md)
- [Professional Communication](professional-communication/SKILL.md)
- [Status Reporting](status-reporting/SKILL.md)
- [AI Prompt Engineering](ai-prompt-engineering/SKILL.md)
---
## Fidelity / iOS Skills
- [Copilot Prompt Engineering](copilot-prompt-engineering/SKILL.md)
- [iOS Swift Answering](ios-swift-answering/SKILL.md)
- [iOS Testing Strategy](ios-testing-strategy/SKILL.md)
- [SwiftUI Expert Skill](swiftui-expert-skill/SKILL.md)
- [SwiftUI XFlow Review](swiftui-xflow-review/SKILL.md)
- [Update SwiftUI APIs](update-swiftui-apis/SKILL.md)
---
## Compatibility Notes
- `.agents/skills/` is the shared skill source intended for Antigravity-compatible and cross-tool discovery.
- `.opencode/skills/` mirrors the installed skills for OpenCode runtime discovery.

View File

@@ -0,0 +1 @@
../../vendor/agent-skills/SwiftUI-Agent-Skill/swiftui-expert-skill

View File

@@ -0,0 +1 @@
../../vendor/agent-skills/SwiftUI-Agent-Skill/.agents/skills/update-swiftui-apis

View File

@@ -19,7 +19,28 @@ Read active profile, if present:
Relevant active work item files, if available:
!`if [ -d project-knowledge/02-work-items ]; then for f in project-knowledge/02-work-items/*.md; do case "$f" in *README.md|*index.md) continue;; esac; echo "\n### $f"; cat "$f"; done; else echo "No work item files available."; fi`
!`python3 - <<'PY'
import re
from pathlib import Path
summary = Path("project-knowledge/01-current/work-items.md")
if not summary.is_file():
print("No work item files available.")
raise SystemExit(0)
text = summary.read_text()
paths = re.findall(r"Detail: `(project-knowledge/02-work-items/[^`]+)`", text)
if not paths:
print("No work item files available.")
raise SystemExit(0)
for rel in paths:
path = Path(rel)
if not path.is_file():
continue
print(f"\n### {rel}")
print(path.read_text())
PY`
User request:

View File

@@ -24,7 +24,28 @@ Active profile, if present:
Detailed active work item files, if available:
!`if [ -d project-knowledge/02-work-items ]; then for f in project-knowledge/02-work-items/*.md; do case "$f" in *README.md|*index.md) continue;; esac; echo "\n### $f"; cat "$f"; done; else echo "No work item files available."; fi`
!`python3 - <<'PY'
import re
from pathlib import Path
summary = Path("project-knowledge/01-current/work-items.md")
if not summary.is_file():
print("No work item files available.")
raise SystemExit(0)
text = summary.read_text()
paths = re.findall(r"Detail: `(project-knowledge/02-work-items/[^`]+)`", text)
if not paths:
print("No work item files available.")
raise SystemExit(0)
for rel in paths:
path = Path(rel)
if not path.is_file():
continue
print(f"\n### {rel}")
print(path.read_text())
PY`
User request:

View File

@@ -6,34 +6,17 @@ Load and internalize the active context for this Fidelity workspace before answe
Use these files as the baseline context:
@README.md
@core/README.md
@core/memory/operational-memory.md
@core/integrations/memory-vault-model.md
@core/integrations/communication-model.md
@profiles/fidelity/profile.md
@agent-memory/README.md
@agent-memory/behavior/agent-behavior.md
@agent-memory/behavior/learning-sessions.md
@agent-memory/behavior/self-maintenance.md
@agent-memory/memory/operational-memory.md
@agent-memory/integrations/memory-interface.md
@agent-memory/integrations/obsidian.md
@agent-memory/integrations/communication-sources.md
@agent-memory/memory/promotion-rules.md
@agent-memory/integrations/technical-verification.md
@project-knowledge/00-start/start-here.md
@project-knowledge/01-current/current-work.md
@project-knowledge/01-current/work-items.md
@project-knowledge/07-maps/current-work.md
@project-knowledge/07-maps/fidelity-domain.md
@project-knowledge/07-maps/work-items.md
@project-knowledge/07-maps/people.md
@project-knowledge/03-context/project.md
@project-knowledge/03-context/process/communication.md
@agent-memory/integrations/technical-verification.md
@agent-memory/workflows/ai-to-ai-prompting.md
@project-knowledge/03-context/process/jira-story-rules.md
@agent-memory/workflows/workspace-model.md
@agent-memory/behavior/agent-behavior.md
@agent-memory/memory/promotion-rules.md
@project-knowledge/03-context/ios/index.md
@project-knowledge/04-people/manager.md
@project-knowledge/04-people/index.md
@@ -45,13 +28,34 @@ Today's canonical daily note, if present:
!`if [ -f project-knowledge/06-daily/$(date +%F).md ]; then cat project-knowledge/06-daily/$(date +%F).md; else echo "No daily note exists for today yet."; fi`
Recent daily notes available:
Latest daily notes available:
!`if [ -d project-knowledge/06-daily ]; then ls -1 project-knowledge/06-daily 2>/dev/null | sort | tail -n 5; else echo "No daily notes directory available."; fi`
!`if [ -d project-knowledge/06-daily ]; then ls -1 project-knowledge/06-daily 2>/dev/null | sort | tail -n 3; else echo "No daily notes directory available."; fi`
Detailed active work item files, if available:
!`if [ -d project-knowledge/02-work-items ]; then for f in project-knowledge/02-work-items/*.md; do case "$f" in *README.md|*index.md) continue;; esac; echo "\n### $f"; cat "$f"; done; else echo "No work item files available."; fi`
!`python3 - <<'PY'
import re
from pathlib import Path
summary = Path("project-knowledge/01-current/work-items.md")
if not summary.is_file():
print("No work item files available.")
raise SystemExit(0)
text = summary.read_text()
paths = re.findall(r"Detail: `(project-knowledge/02-work-items/[^`]+)`", text)
if not paths:
print("No work item files available.")
raise SystemExit(0)
for rel in paths:
path = Path(rel)
if not path.is_file():
continue
print(f"\n### {rel}")
print(path.read_text())
PY`
Latest Mattermost context, if available:

View File

@@ -13,11 +13,44 @@ Use this when the user asks for:
Run sync:
!`if [ -n "$AIW_MATTERMOST_SYNC_CMD" ]; then bash -lc "$AIW_MATTERMOST_SYNC_CMD"; elif [ -n "$FIDELITY_MATTERMOST_SYNC_CMD" ]; then bash -lc "$FIDELITY_MATTERMOST_SYNC_CMD"; elif [ -f scripts/mattermost/sync.sh ]; then bash scripts/mattermost/sync.sh; else echo "No Mattermost sync command is configured."; fi`
!`start=$(date +%s); if [ -n "$AIW_MATTERMOST_SYNC_CMD" ]; then bash -lc "$AIW_MATTERMOST_SYNC_CMD"; elif [ -n "$FIDELITY_MATTERMOST_SYNC_CMD" ]; then bash -lc "$FIDELITY_MATTERMOST_SYNC_CMD"; elif [ -f scripts/mattermost/sync.sh ]; then bash scripts/mattermost/sync.sh; else echo "No Mattermost sync command is configured."; fi; status=$?; end=$(date +%s); echo "__MATTERMOST_SYNC_SECONDS__=$((end - start))"; exit "$status"`
Read refreshed Mattermost context:
Read a focused slice of refreshed Mattermost context:
!`if [ -s ai/inbox/mattermost-latest.md ]; then cat ai/inbox/mattermost-latest.md; elif [ -s scripts/mattermost/generated/mattermost_context.jsonl ]; then cat scripts/mattermost/generated/mattermost_context.jsonl; else echo "No Mattermost context available after sync."; fi`
!`python3 - <<'PY'
import json
from pathlib import Path
paths = [
Path("ai/inbox/mattermost-latest.md"),
Path("scripts/mattermost/generated/mattermost_context.jsonl"),
]
source = next((path for path in paths if path.is_file() and path.stat().st_size > 0), None)
if not source:
print("No Mattermost context available after sync.")
raise SystemExit(0)
records = []
for line in source.read_text().splitlines():
line = line.strip()
if not line:
continue
try:
records.append(json.loads(line))
except json.JSONDecodeError:
continue
manager_names = {"jeff", "jeff.dewitte"}
manager_records = [
record for record in records
if str(record.get("username", "")).lower() in manager_names
]
focused = manager_records[-10:] if manager_records else records[-15:]
for record in focused:
print(json.dumps(record, ensure_ascii=False))
PY`
User request:
@@ -26,15 +59,18 @@ $ARGUMENTS
Instructions:
- Do not answer from old conversation memory.
- Use only the refreshed Mattermost output above.
- Use only the focused refreshed Mattermost output above.
- If the user asks for the current manager/stakeholder, filter messages by the profile mapping when visible; for the Fidelity profile, also match `jeff` and `jeff.dewitte`.
- If multiple messages match, return the newest matching message first.
- Include timestamp, channel, sender, and concise summary.
- If the message changes project context, update the appropriate workspace memory after answering, writing to `project-knowledge/` first.
- Do not edit workspace memory in this command.
- If the message appears to change project context, report it as a memory update candidate and name the likely target file.
- Use `/communication-sync` or an explicit user request to promote the fact after the latest-message answer is complete.
- If sync fails or no refreshed context is available, say that directly and do not infer from stale context.
- If a write or patch attempt fails in this flow, stop immediately and return the latest-message answer plus the failed target; do not retry.
Return:
1. Latest matching message
2. Why it matters
3. Any memory update made
3. Memory update candidate, if any

View File

@@ -12,7 +12,6 @@ Read:
@project-knowledge/01-current/current-work.md
@project-knowledge/01-current/work-items.md
@project-knowledge/03-context/project.md
@project-knowledge/03-context/workstreams/index.md
@project-knowledge/03-context/process/communication.md
@project-knowledge/04-people/manager.md
@project-knowledge/04-people/index.md
@@ -27,7 +26,28 @@ Latest Mattermost context, if available:
Detailed active work item files, if available:
!`if [ -d project-knowledge/02-work-items ]; then for f in project-knowledge/02-work-items/*.md; do case "$f" in *README.md|*index.md) continue;; esac; echo "\n### $f"; cat "$f"; done; else echo "No work item files available."; fi`
!`python3 - <<'PY'
import re
from pathlib import Path
summary = Path("project-knowledge/01-current/work-items.md")
if not summary.is_file():
print("No work item files available.")
raise SystemExit(0)
text = summary.read_text()
paths = re.findall(r"Detail: `(project-knowledge/02-work-items/[^`]+)`", text)
if not paths:
print("No work item files available.")
raise SystemExit(0)
for rel in paths:
path = Path(rel)
if not path.is_file():
continue
print(f"\n### {rel}")
print(path.read_text())
PY`
User draft or rough notes:

View File

@@ -4,57 +4,82 @@ description: Draft a standup from the latest Fidelity workspace context
Generate a standup update using the latest workspace state.
First, refresh Mattermost context before drafting:
Temporal context. Read this before interpreting `today`, `yesterday`, `previous workday`, or `last workday`:
!`python3 - <<'PY'
from datetime import datetime, timedelta
now = datetime.now().astimezone()
today = now.date()
calendar_yesterday = today - timedelta(days=1)
default_previous_workday = calendar_yesterday
while default_previous_workday.weekday() >= 5:
default_previous_workday -= timedelta(days=1)
print("## Temporal Context")
print(f"current_time: {now.isoformat()}")
print(f"today: {today.isoformat()} ({today.strftime('%A')})")
print(f"calendar_yesterday: {calendar_yesterday.isoformat()} ({calendar_yesterday.strftime('%A')})")
print(f"default_previous_workday: {default_previous_workday.isoformat()} ({default_previous_workday.strftime('%A')})")
print("standup_rule: Generate the report for today. The previous-work section must describe work from calendar_yesterday when it was a workday; otherwise use the latest prior day with Mattermost activity.")
PY`
First, refresh Mattermost before drafting. This is mandatory for start-of-day standups and must not be skipped:
!`python3 - <<'PY'
import os
import subprocess
from pathlib import Path
from datetime import datetime
cmd = os.environ.get("AIW_MATTERMOST_SYNC_CMD") or os.environ.get("FIDELITY_MATTERMOST_SYNC_CMD")
if cmd:
result = subprocess.run(["bash", "-lc", cmd], capture_output=True, text=True)
elif Path("scripts/mattermost/sync.sh").is_file():
result = subprocess.run(["bash", "scripts/mattermost/sync.sh"], capture_output=True, text=True)
else:
today = datetime.now().astimezone().date().isoformat()
commands = []
if Path("scripts/mattermost/sync.sh").is_file():
commands.append(("latest", ["bash", "scripts/mattermost/sync.sh"]))
commands.append(("previous-workday", ["bash", "scripts/mattermost/sync.sh", "--previous-workday", "--today", today]))
elif cmd:
commands.append(("configured", ["bash", "-lc", cmd]))
if not commands:
print("No Mattermost sync command configured.")
raise SystemExit(0)
failed = False
for label, command in commands:
result = subprocess.run(command, capture_output=True, text=True)
print(f"__MATTERMOST_SYNC_LABEL__={label}")
print(f"__MATTERMOST_SYNC_RETURN_CODE__={result.returncode}")
if result.returncode != 0:
failed = True
print("__MATTERMOST_SYNC_FAILED__")
if result.stdout:
print(result.stdout.strip())
if result.stderr:
print(result.stderr.strip())
else:
if result.stdout.strip():
print(result.stdout.strip())
if result.stderr.strip():
print(result.stderr.strip())
if failed:
raise SystemExit(0)
PY`
Read:
@prompts/standup.md
@project-knowledge/00-start/start-here.md
@project-knowledge/01-current/current-work.md
@project-knowledge/01-current/work-items.md
@project-knowledge/03-context/project.md
@project-knowledge/03-context/workstreams/index.md
@project-knowledge/03-context/workstreams/flow-page-references.md
@project-knowledge/03-context/process/communication.md
@project-knowledge/03-context/process/jira-story-rules.md
@project-knowledge/04-people/manager.md
Previous workday Mattermost context, if present:
!`bash scripts/mattermost/sync.sh --previous-workday --today "$(date +%F)"`
Today's log, if present:
!`if [ -f project-knowledge/06-daily/$(date +%F).md ]; then cat project-knowledge/06-daily/$(date +%F).md; else echo "No daily note exists for today yet."; fi`
Latest Mattermost context, preferring inbox and falling back to generated JSONL:
Latest refreshed Mattermost context, if present:
!`if [ -s ai/inbox/mattermost-latest.md ]; then cat ai/inbox/mattermost-latest.md; elif [ -s scripts/mattermost/generated/mattermost_context.jsonl ]; then cat scripts/mattermost/generated/mattermost_context.jsonl; else echo "No Mattermost context available."; fi`
!`if [ -s ai/inbox/mattermost-latest.md ]; then cat ai/inbox/mattermost-latest.md; elif [ -s scripts/mattermost/generated/mattermost_context.jsonl ]; then cat scripts/mattermost/generated/mattermost_context.jsonl; else echo "No refreshed Mattermost context available."; fi`
Detailed active work item files, if available:
@@ -84,6 +109,7 @@ PY`
Before drafting:
- use `status-reporting` when available
- Mattermost refresh is mandatory for standup; do not draft from stale workspace memory if the refresh did not run
- update workspace memory if the refreshed context introduced clear high-confidence project facts
- prefer existing memory when the latest context is ambiguous
- treat the previous workday Mattermost context as the source for the `Yesterday` section, even when the previous calendar day was a weekend, holiday, or OOO day

View File

@@ -40,7 +40,28 @@ Latest Mattermost context, if available:
Detailed active work item files, if available:
!`if [ -d project-knowledge/02-work-items ]; then for f in project-knowledge/02-work-items/*.md; do case "$f" in *README.md|*index.md) continue;; esac; echo "\n### $f"; cat "$f"; done; else echo "No work item files available."; fi`
!`python3 - <<'PY'
import re
from pathlib import Path
summary = Path("project-knowledge/01-current/work-items.md")
if not summary.is_file():
print("No work item files available.")
raise SystemExit(0)
text = summary.read_text()
paths = re.findall(r"Detail: `(project-knowledge/02-work-items/[^`]+)`", text)
if not paths:
print("No work item files available.")
raise SystemExit(0)
for rel in paths:
path = Path(rel)
if not path.is_file():
continue
print(f"\n### {rel}")
print(path.read_text())
PY`
Requirements:

View File

@@ -6,37 +6,20 @@ Load and internalize the reusable workspace core and the active project context
Read core:
@core/README.md
@core/memory/operational-memory.md
@core/integrations/memory-vault-model.md
@core/integrations/communication-model.md
@core/profiles/create-project-profile.md
@agent-memory/README.md
@profiles/fidelity/profile.md
@agent-memory/behavior/agent-behavior.md
@agent-memory/behavior/learning-sessions.md
@agent-memory/behavior/self-maintenance.md
@agent-memory/memory/operational-memory.md
@agent-memory/integrations/memory-interface.md
@agent-memory/integrations/obsidian.md
@agent-memory/integrations/communication-sources.md
@agent-memory/memory/promotion-rules.md
@agent-memory/integrations/technical-verification.md
Read active workspace memory:
@README.md
@project-knowledge/00-start/start-here.md
@project-knowledge/00-start/onboarding.md
@project-knowledge/01-current/current-work.md
@project-knowledge/01-current/work-items.md
@project-knowledge/07-maps/current-work.md
@project-knowledge/07-maps/fidelity-domain.md
@project-knowledge/07-maps/work-items.md
@project-knowledge/07-maps/people.md
@project-knowledge/03-context/project.md
@project-knowledge/03-context/process/communication.md
@agent-memory/integrations/technical-verification.md
@agent-memory/memory/context-maintenance.md
@agent-memory/workflows/workspace-model.md
@agent-memory/behavior/agent-behavior.md
@agent-memory/memory/promotion-rules.md
@project-knowledge/03-context/ios/index.md
@project-knowledge/04-people/manager.md
@project-knowledge/04-people/index.md
@@ -52,13 +35,34 @@ Today's canonical daily note, if present:
!`if [ -f project-knowledge/06-daily/$(date +%F).md ]; then cat project-knowledge/06-daily/$(date +%F).md; else echo "No daily note exists for today yet."; fi`
Recent daily notes available:
Latest daily notes available:
!`if [ -d project-knowledge/06-daily ]; then ls -1 project-knowledge/06-daily 2>/dev/null | sort | tail -n 5; else echo "No daily notes directory available."; fi`
!`if [ -d project-knowledge/06-daily ]; then ls -1 project-knowledge/06-daily 2>/dev/null | sort | tail -n 3; else echo "No daily notes directory available."; fi`
Detailed active work item files, if available:
!`if [ -d project-knowledge/02-work-items ]; then for f in project-knowledge/02-work-items/*.md; do case "$f" in *README.md|*index.md) continue;; esac; echo "\n### $f"; cat "$f"; done; else echo "No work item files available."; fi`
!`python3 - <<'PY'
import re
from pathlib import Path
summary = Path("project-knowledge/01-current/work-items.md")
if not summary.is_file():
print("No work item files available.")
raise SystemExit(0)
text = summary.read_text()
paths = re.findall(r"Detail: `(project-knowledge/02-work-items/[^`]+)`", text)
if not paths:
print("No work item files available.")
raise SystemExit(0)
for rel in paths:
path = Path(rel)
if not path.is_file():
continue
print(f"\n### {rel}")
print(path.read_text())
PY`
Latest communication inbox, if available:

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "vendor/agent-skills/SwiftUI-Agent-Skill"]
path = vendor/agent-skills/SwiftUI-Agent-Skill
url = https://github.com/AvdLee/SwiftUI-Agent-Skill.git

View File

@@ -26,6 +26,7 @@ Behavior rules:
- Daily notes should include `focus`, `work-items`, and `blockers` when those values are clear.
- Before answering a prompt that depends on current state, verify the latest relevant files instead of relying only on conversation history.
- If the prompt asks for the latest Mattermost message, the last message from Jeff/current manager, or what someone just said, force a Mattermost refresh before answering and do not rely on stale inbox context.
- Treat latest-message prompts as read-first: answer from refreshed evidence and report memory update candidates instead of editing canonical memory by default.
- For learning-style questions, answer from known context and verified facts only; explicitly label unknowns, assumptions, and inferences.
- For learning sessions, prioritize durable architecture, process, ownership, debugging strategy, release mechanics, domain concepts, and decision rules over transient ticket status.
- If the user asks what to clarify, ask 3 to 5 high-leverage questions that would help a senior iOS engineer ramp into the project; include why each question matters.
@@ -33,7 +34,7 @@ Behavior rules:
- If missing context materially affects the answer, ask a concise clarification question instead of inventing details.
- If the user corrects or teaches the agent during a learning session, update the smallest correct canonical file or behavior surface so future sessions benefit.
- For any meaningful prompt, decide whether the interaction adds, corrects, or sharpens project memory.
- When the user provides new durable information, update the right workspace files before or while answering.
- When the user provides new durable information, update the right workspace files during the same turn when the destination is clear, but do not delay a straightforward answer just to create or reorganize memory.
- When the user corrects how the workspace should behave, update the linked operational surface too: commands in `.opencode/commands/`, prompt templates in `prompts/`, agent rules in `AGENTS.md` or `.opencode/agents/`, skills in `.opencode/skills/`, and agent operating rules in `agent-memory/` when those files control the behavior.
- If existing context is stale, correct it directly instead of leaving conflicting versions.
- Promote information carefully:
@@ -54,6 +55,9 @@ Behavior rules:
- Write canonical memory to `project-knowledge/`.
- Update preexisting memory when a new prompt clarifies or corrects something already stored.
- Do not wait for a dedicated sync command if the correct memory update is already obvious.
- For analysis, drafting, review, or translation prompts, answer first and persist second unless saving the fact is required to produce the answer safely.
- Avoid creating brand-new canonical notes in the middle of a response unless the user explicitly asked for persistence or the new note is the smallest correct update.
- If a non-essential memory patch fails verification, stop retrying and return the answer plus the intended target file.
- Do not leave behavior-only corrections only in daily logs. If a correction should affect future output, update the tool or instruction that produces that output.
- If the memory interface or Obsidian adapter fails, continue with direct Markdown operations when safe and do not promote the failure as project memory.
- Do not over-promote uncertain information. Keep uncertain items in the daily log.

View File

@@ -13,33 +13,21 @@ export const FidelityCompaction = async ({ directory }) => {
return {
"experimental.session.compacting": async (_input, output) => {
const baseFiles = [
"README.md",
"core/README.md",
"core/memory/operational-memory.md",
"core/integrations/memory-vault-model.md",
"core/integrations/communication-model.md",
"profiles/fidelity/profile.md",
"agent-memory/README.md",
"agent-memory/behavior/agent-behavior.md",
"agent-memory/behavior/learning-sessions.md",
"agent-memory/memory/promotion-rules.md",
"agent-memory/memory/context-maintenance.md",
"agent-memory/integrations/technical-verification.md",
"agent-memory/workflows/workspace-model.md",
"agent-memory/workflows/ai-to-ai-prompting.md",
"project-knowledge/00-start/start-here.md",
"project-knowledge/01-current/current-work.md",
"project-knowledge/01-current/work-items.md",
"project-knowledge/03-context/project.md",
"project-knowledge/03-context/ios/index.md",
"project-knowledge/03-context/ios/current-practices.md",
"project-knowledge/03-context/ios/project-swift-guidance.md",
"project-knowledge/03-context/systems/index.md",
"project-knowledge/03-context/workstreams/index.md",
"project-knowledge/03-context/process/communication.md",
"project-knowledge/03-context/ios/index.md",
"project-knowledge/03-context/ios/project-swift-guidance.md",
"project-knowledge/04-people/manager.md",
"project-knowledge/04-people/index.md",
"project-knowledge/05-decisions/rest-vs-graphql.md",
"project-knowledge/05-decisions/discourse-handling.md",
]
const sections = []
@@ -56,7 +44,7 @@ export const FidelityCompaction = async ({ directory }) => {
const logs = (await readdir(logsDir))
.filter((name) => name.endsWith(".md"))
.sort()
.slice(-2)
.slice(-1)
for (const logName of logs) {
const content = await safeRead(path.join(logsDir, logName))

View File

@@ -13,6 +13,12 @@ function nowIso() {
return new Date().toISOString()
}
function envFlag(name, defaultValue = false) {
const value = process.env[name]
if (value === undefined) return defaultValue
return ["1", "true", "yes", "on"].includes(value.trim().toLowerCase())
}
async function resolveSyncCommand(directory) {
const configured =
process.env.AIW_MATTERMOST_SYNC_CMD?.trim() ||
@@ -66,30 +72,16 @@ function requiresFreshMattermost(promptText) {
.replace(/[\u0300-\u036f]/g, "")
.toLowerCase()
const freshnessTerms = [
"ultimo",
"ultimos",
"ultima",
"ultimas",
"latest",
"last",
"reciente",
"recent",
"nuevo",
"new",
"actualiza",
"sync",
"sincroniza",
"revisa",
"dijo",
"menciono",
"respondio",
"contesto",
"check",
"look at",
"said",
"mentioned",
"replied",
const freshnessPatterns = [
/\bultimo(?:s|a|as)?\s+(?:mensaje|mensajes|respuesta|respuestas|update|updates)\b/,
/\bmensaje(?:s)?\s+(?:mas\s+)?reciente(?:s)?\b/,
/\bque\s+(?:dijo|menciono|respondio|contesto)\b/,
/\b(?:dijo|menciono|respondio|contesto)\s+(?:jeff|manager|supervisor)\b/,
/\b(?:latest|last|recent)\s+(?:message|messages|reply|replies|update|updates)\b/,
/\bwhat\s+did\s+.+\s+(?:say|mention|reply)\b/,
/\b(?:said|mentioned|replied)\s+(?:jeff|manager|supervisor)\b/,
/\b(?:sync|refresh|sincroniza|actualiza)\s+(?:mattermost|mensajes|messages|inbox)\b/,
/\b(?:revisa|check|look\s+at)\s+(?:mattermost|mensajes|messages|inbox)\b/,
]
const mattermostTerms = [
@@ -123,10 +115,8 @@ function requiresFreshMattermost(promptText) {
...configuredTerms,
]
return (
freshnessTerms.some((term) => text.includes(term)) &&
return freshnessPatterns.some((pattern) => pattern.test(text)) &&
sourceTerms.some((term) => text.includes(term))
)
}
export const MattermostInbox = async ({ $, directory, client }) => {
@@ -152,6 +142,7 @@ export const MattermostInbox = async ({ $, directory, client }) => {
if (!options.force && now - lastSyncAt < minIntervalMs) return
lastSyncAt = now
const syncStartedAt = Date.now()
const inboxDir = path.join(directory, "ai/inbox")
const latestPath = path.join(inboxDir, "mattermost-latest.md")
@@ -179,6 +170,7 @@ export const MattermostInbox = async ({ $, directory, client }) => {
await writeStatus(statusPath, {
syncedAt: nowIso(),
durationMs: Date.now() - syncStartedAt,
reason,
forced: Boolean(options.force),
changed: previous !== `${output}\n` && previous !== output,
@@ -188,6 +180,7 @@ export const MattermostInbox = async ({ $, directory, client }) => {
} else {
await writeStatus(statusPath, {
syncedAt: nowIso(),
durationMs: Date.now() - syncStartedAt,
reason,
forced: Boolean(options.force),
changed: false,
@@ -199,6 +192,7 @@ export const MattermostInbox = async ({ $, directory, client }) => {
} catch (error) {
await writeStatus(statusPath, {
syncedAt: nowIso(),
durationMs: Date.now() - syncStartedAt,
reason,
forced: Boolean(options.force),
changed: false,
@@ -223,13 +217,20 @@ export const MattermostInbox = async ({ $, directory, client }) => {
return {
event: async ({ event }) => {
if (event.type === "session.created") {
if (
event.type === "session.created" &&
envFlag("AIW_MATTERMOST_SYNC_ON_SESSION", false)
) {
await sync("session.created")
}
if (event.type === "tui.prompt.append") {
const promptText = extractPromptText(event)
const forceFreshMattermost = requiresFreshMattermost(promptText)
const allowPromptSync = envFlag("AIW_MATTERMOST_SYNC_ON_PROMPT", false)
if (!forceFreshMattermost && !allowPromptSync) return
await sync(
forceFreshMattermost
? "tui.prompt.append:fresh-mattermost-request"

View File

@@ -18,7 +18,9 @@ Skills available to the workspace agent.
- [Copilot Prompt Engineering](copilot-prompt-engineering/SKILL.md)
- [iOS Swift Answering](ios-swift-answering/SKILL.md)
- [iOS Testing Strategy](ios-testing-strategy/SKILL.md)
- [SwiftUI Expert Skill](swiftui-expert-skill/SKILL.md)
- [SwiftUI XFlow Review](swiftui-xflow-review/SKILL.md)
- [Update SwiftUI APIs](update-swiftui-apis/SKILL.md)
---

View File

@@ -0,0 +1 @@
../../.agents/skills/swiftui-expert-skill

View File

@@ -0,0 +1 @@
../../.agents/skills/update-swiftui-apis

View File

@@ -9,40 +9,29 @@ OpenCode should treat this project as a persistent context layer used to:
- draft standups and Mattermost messages
- improve communication for the current manager or stakeholder in natural professional English
## Always-Loaded Context
## Hot Context
The detailed operating rules live in:
Keep the always-loaded context small. The hot set is:
- `project-knowledge/00-start/start-here.md`
- `agent-memory/README.md`
- `profiles/fidelity/profile.md`
- `agent-memory/behavior/agent-behavior.md`
- `agent-memory/behavior/learning-sessions.md`
- `agent-memory/behavior/self-maintenance.md`
- `agent-memory/memory/operational-memory.md`
- `agent-memory/memory/context-maintenance.md`
- `agent-memory/workflows/workspace-architecture.md`
- `agent-memory/memory/promotion-rules.md`
- `agent-memory/integrations/technical-verification.md`
- `agent-memory/workflows/ai-to-ai-prompting.md`
- `project-knowledge/00-start/start-here.md`
- `project-knowledge/01-current/current-work.md`
- `project-knowledge/01-current/work-items.md`
- `project-knowledge/03-context/project.md`
- `project-knowledge/03-context/ios/index.md`
- `project-knowledge/03-context/ios/current-practices.md`
- `project-knowledge/03-context/ios/project-swift-guidance.md`
- `project-knowledge/03-context/systems/index.md`
- `project-knowledge/03-context/workstreams/index.md`
- `project-knowledge/03-context/process/communication.md`
- `agent-memory/integrations/technical-verification.md`
- `agent-memory/workflows/ai-to-ai-prompting.md`
- `agent-memory/workflows/workspace-model.md`
- `agent-memory/memory/promotion-rules.md`
- `agent-memory/integrations/memory-interface.md`
- `agent-memory/integrations/obsidian.md`
- `agent-memory/integrations/communication-sources.md`
- `core/integrations/memory-vault-model.md`
- `project-knowledge/03-context/ios/index.md`
- `project-knowledge/03-context/ios/project-swift-guidance.md`
- `project-knowledge/04-people/manager.md`
- `project-knowledge/04-people/index.md`
- `project-knowledge/02-work-items/index.md`
These are also loaded through `opencode.json`.
Load everything else lazily when the task actually needs it.
Do not preemptively load broad context sets, all work-item files, or all process notes unless the current task clearly requires them.
## Required Behavior
@@ -53,17 +42,23 @@ These are also loaded through `opencode.json`.
- Keep Obsidian Bases clean: templates in `project-knowledge/09-templates/` must not be treated as real notes, and role mapping files such as `project-knowledge/04-people/manager.md` must not be typed as people.
- Maintain useful project-note properties when editing canonical notes, especially work-item relationships (`systems`, `workstreams`, `people`, `related`) and daily note fields (`focus`, `work-items`, `blockers`).
- Before answering questions that depend on current work state, inspect `project-knowledge/01-current/current-work.md` and the latest relevant daily note under `project-knowledge/06-daily/`.
- Prefer lazy loading over eager loading. Pull in only the smallest relevant files for the active task.
- If `ai/inbox/mattermost-latest.md` exists, inspect it for fresher communication context before answering standup, status, or manager-message prompts.
- If the user asks for the latest/last/recent Mattermost message, the latest message from Jeff/current manager, or what someone just said, synchronize Mattermost first instead of relying on existing inbox context.
- If automatic refresh is uncertain, use the explicit latest-message flow: run the Mattermost sync command, then answer from the refreshed inbox only.
- Treat latest-message flows as read-first. Report memory update candidates, but do not edit canonical memory from that command unless the user explicitly asks to promote the fact.
- For learning-style questions, answer from known context and verified facts only; label unknowns, assumptions, and inferences instead of inventing missing details.
- For learning sessions, prioritize durable architecture, process, ownership, debugging strategy, release mechanics, domain concepts, and decision rules over transient ticket status.
- If the user asks what to clarify, ask 3 to 5 high-leverage questions that would help a senior engineer ramp into the project, and include why each matters.
- Ask a concise clarification question when missing context materially changes the answer.
- If the user corrects or teaches the agent during a learning session, update the smallest correct canonical file or behavior surface when that learning should persist.
- For any meaningful prompt, decide whether the interaction introduces or corrects project memory.
- For analysis, review, translation, or drafting requests, answer first unless a memory update is required to avoid losing a clear durable fact.
- Do not create new canonical notes before answering unless the user asked to save the information, the destination is obvious, and the write is small and non-blocking.
- Prefer updating existing canonical files over creating new files during the critical path of a user-facing answer.
- If a sync command, extraction script, or inbox refresh fails, do not update logs, state, or context files from that failed attempt.
- Treat sync failures as operational errors, not project context.
- If a patch or edit verification fails while making a non-essential memory update, stop retrying and return the user-facing answer with the failed target noted.
- `mattermost-sync` should automatically promote high-confidence project facts without asking what to promote.
- Prefer `project-knowledge/06-daily/` as the default destination for new Mattermost-derived facts.
- Promote to `project-knowledge/01-current/current-work.md` only when the fact materially changes active work over the next few days.
@@ -76,6 +71,7 @@ These are also loaded through `opencode.json`.
- If a new prompt corrects prior understanding, update the canonical file directly instead of keeping both versions alive.
- Do not ask what should be saved when the correct destination is already clear.
- If the user provides durable new facts, update the appropriate context files instead of leaving the new information only in chat history.
- When the prompt is primarily asking for analysis of a screenshot, message, or document, do not interrupt the answer to perform proactive note creation unless that persistence is the explicit goal.
- When creating a new canonical note from a known type, prefer `scripts/memory/memory.sh create <type> <slug> [title]` so type-to-folder routing stays centralized.
- If the Obsidian CLI adapter fails, fall back to direct Markdown operations and treat the failure as tooling status, not project context.
- If a previous context file is now stale or inaccurate, update that file directly.

View File

@@ -7,8 +7,6 @@ Shared rules and context already live in the normal workspace files. Do not dupl
Read these first:
@./AGENTS.md
@./README.md
@./agent-memory/README.md
@./project-knowledge/00-start/start-here.md
@./project-knowledge/01-current/current-work.md
@./project-knowledge/01-current/work-items.md
@@ -22,16 +20,10 @@ Read these first:
- `project-knowledge/` is canonical project memory.
- `agent-memory/` is agent operating memory.
## Gemini-Specific Mandatory Loop (Real-Time Auto-Documentation)
## Gemini-Specific Operating Notes
At the end of EVERY conversational turn, you MUST evaluate the interaction as a senior Obsidian documentation expert:
1. **Analyze for Memory Impact:** Did the user's prompt or your subsequent action reveal new technical context, resolve an open question, change an architectural assumption, or shift current priorities?
2. **Identify Target Canonical Files:** If memory impact is detected, identify WHERE in the `project-knowledge/` directory this information belongs. This is NOT limited to daily logs. It could be:
- `01-current/current-work.md` (priority shifts, new blockers)
- `02-work-items/*.md` (story updates, bug reproduction steps)
- `03-context/` (system architecture, processes, workflows)
- `04-people/` (stakeholder involvement)
- `06-daily/YYYY-MM-DD.md` (daily findings)
3. **Proactive Update:** You MUST use your file editing tools (`replace_file_content` / `multi_replace_file_content`) to inject the new context or CORRECT existing stale context in the appropriate files BEFORE concluding your response.
4. **No Explicit Prompt Needed:** Do not wait for the user to say "document this". Auto-document implicitly. Ensure you do not pollute the workspace with unverified guesses; only document confirmed context or active hypotheses.
- Keep the hot context small and load additional files lazily based on the active task.
- Follow `AGENTS.md` as the shared source of truth for answer-first behavior, memory promotion, and lazy loading.
- For analysis, review, translation, or drafting prompts, answer first and persist second unless saving the fact is clearly required to produce a safe answer.
- Do not create new canonical notes in the critical path of a simple answer unless the user explicitly asked to save the information or the destination is obvious and non-blocking.
- When memory should be updated, prefer the smallest correct change to `project-knowledge/` and avoid duplicating stale and corrected versions.

View File

@@ -15,7 +15,7 @@ Make workspace memory maintenance part of the agent's normal job, not a separate
## Default Agent Behavior (Real-Time Auto-Documentation)
For EVERY meaningful prompt, the agent MUST execute a real-time auto-documentation loop. It is not an optional workflow; it is the core of the agent's job.
For every meaningful prompt, the agent must evaluate whether a memory update is needed in the same turn. Auto-documentation is part of the job, but it must not dominate the critical path of simple user-facing answers.
This applies to:
@@ -27,10 +27,13 @@ This applies to:
- debugging discussions
- corrections to previous understanding
The agent MUST NOT wait for a separate promotion command. The agent MUST proactively use file editing tools to update `project-knowledge/` (including 01-current, 02-work-items, 03-context, 04-people, 06-daily) within the SAME conversational turn if new information is detected or if prior context becomes stale.
The agent must not wait for a separate promotion command. The agent should proactively update `project-knowledge/` (including 01-current, 02-work-items, 03-context, 04-people, 06-daily) within the same conversational turn when new information is clear, durable, and the destination is obvious.
- When editing `project-knowledge/`, write as a human engineer maintaining shared project documentation.
- Keep agent-operating logic out of `project-knowledge/`; store that logic in prompts, commands, skills, agents, or `agent-memory/`.
- Answer-first rule: when the user's main goal is analysis, review, translation, or drafting, answer first unless persistence is required to avoid losing a clear durable fact.
- Do not create a brand-new canonical note during the critical path of the answer unless the user explicitly asked to save the fact or the new note is the smallest correct update.
- Prefer updating an existing canonical note over creating a new file when both are valid.
---

View File

@@ -21,6 +21,12 @@ Mattermost is the current live communication connector.
- Generated extraction artifacts stay under `scripts/mattermost/generated/`.
- Failed syncs must not update project knowledge.
- Latest-message requests must refresh Mattermost before answering.
- Latest-message requests are read-first. The agent may identify a memory update candidate, but should not edit `project-knowledge/` from the latest-message command unless the user explicitly asks to promote the fact.
- Standup generation is a separate required-refresh flow: it must fetch Mattermost before drafting, even though general prompts should not sync automatically.
- Do not refresh Mattermost just because a prompt mentions a manager or stakeholder.
- Treat document review, message polishing, translation, and "does this align with Jeff's expectations?" prompts as normal drafting tasks unless the user explicitly asks for the latest message or fresh Mattermost evidence.
- The OpenCode plugin syncs automatically only for explicit latest-message requests by default.
- Optional aggressive sync can be enabled with `AIW_MATTERMOST_SYNC_ON_SESSION=true` or `AIW_MATTERMOST_SYNC_ON_PROMPT=true`, but these should stay off for low-latency daily use.
---
@@ -31,4 +37,3 @@ Slack export import is the current historical archive connector.
- Archive evidence stays outside `project-knowledge/`.
- Promote only durable project facts, people context, process rules, or historical architecture lessons.
- Do not promote dated status details unless they explain current context.

View File

@@ -27,6 +27,8 @@ Capture reusable prompting lessons so the agent does not need to re-research the
- Use concrete anti-patterns when a recurring failure mode is known; models respond better to explicit "do not do X" guidance than to general advice alone.
- Prefer source-bound selection rules when stale or overly broad context can pollute the answer.
- If a task depends on chronology, state chronology explicitly as an output rule.
- If a task depends on dates, inject an explicit temporal context block near the top of the command: current timestamp, today, calendar yesterday, and the default previous workday. Do not rely on the model to infer this from session history.
- Delegate date arithmetic to code or shell commands and feed the result back to the model as data.
- If concision matters, define how to compress: what should be merged, what should remain split, and what should be omitted.
- If the output is meant to be sent directly, make "copy/paste ready" part of the contract.
- Avoid mixing task logic with human-facing project documentation; reusable prompting logic belongs in prompts, commands, skills, or agent memory.
@@ -36,6 +38,7 @@ Capture reusable prompting lessons so the agent does not need to re-research the
## Standup-Specific Lessons
- The model should not infer "worked yesterday" from durable status alone.
- The standup command should anchor `today`, `yesterday`, and `previous workday` with absolute dates before reading logs or Mattermost evidence.
- `Yesterday` should be tied to previous-workday evidence first, then disambiguated with current memory.
- Only active work items should be expanded by default; avoid loading every ticket note when generating short status output.
- Future-sprint work should be excluded from `Today` unless it is a real blocker or the user explicitly wants forward-looking planning.

View File

@@ -2,6 +2,16 @@
"$schema": "https://opencode.ai/config.json",
"default_agent": "fidelity",
"share": "manual",
"snapshot": false,
"watcher": {
"ignore": [
".git/**",
"archives/**",
".opencode/node_modules/**",
"scripts/*/generated/**",
"project-knowledge/attachments/**"
]
},
"mcp": {
"obsidian": {
"type": "local",
@@ -53,51 +63,20 @@
"doom_loop": "ask"
},
"instructions": [
"./README.md",
"./core/README.md",
"./core/memory/operational-memory.md",
"./core/integrations/memory-vault-model.md",
"./core/integrations/communication-model.md",
"./core/integrations/obsidian-model.md",
"./core/profiles/create-project-profile.md",
"./profiles/fidelity/profile.md",
"./agent-memory/README.md",
"./agent-memory/behavior/agent-behavior.md",
"./agent-memory/behavior/learning-sessions.md",
"./agent-memory/behavior/self-maintenance.md",
"./agent-memory/memory/operational-memory.md",
"./agent-memory/memory/promotion-rules.md",
"./agent-memory/memory/context-maintenance.md",
"./agent-memory/integrations/memory-interface.md",
"./agent-memory/integrations/obsidian.md",
"./agent-memory/integrations/communication-sources.md",
"./agent-memory/integrations/technical-verification.md",
"./agent-memory/workflows/ai-to-ai-prompting.md",
"./agent-memory/workflows/workspace-model.md",
"./agent-memory/workflows/workspace-architecture.md",
"./project-knowledge/00-start/start-here.md",
"./project-knowledge/00-start/onboarding.md",
"./project-knowledge/00-start/glossary.md",
"./project-knowledge/01-current/current-work.md",
"./project-knowledge/01-current/work-items.md",
"./project-knowledge/07-maps/current-work.md",
"./project-knowledge/07-maps/fidelity-domain.md",
"./project-knowledge/07-maps/work-items.md",
"./project-knowledge/07-maps/people.md",
"./project-knowledge/03-context/project.md",
"./project-knowledge/03-context/process/communication.md",
"./project-knowledge/03-context/process/jira-story-rules.md",
"./project-knowledge/03-context/process/communication-rules.md",
"./project-knowledge/03-context/process/pull-requests.md",
"./project-knowledge/03-context/ios/index.md",
"./project-knowledge/03-context/ios/current-practices.md",
"./project-knowledge/03-context/ios/project-swift-guidance.md",
"./project-knowledge/03-context/systems/index.md",
"./project-knowledge/03-context/workstreams/index.md",
"./project-knowledge/03-context/workstreams/flow-page-references.md",
"./project-knowledge/04-people/manager.md",
"./project-knowledge/04-people/index.md",
"./project-knowledge/05-decisions/rest-vs-graphql.md",
"./project-knowledge/05-decisions/discourse-handling.md"
"./project-knowledge/04-people/index.md"
]
}

View File

@@ -125,4 +125,6 @@ Domain-specific:
- `ios-swift-answering`
- `ios-testing-strategy`
- `swiftui-expert-skill`
- `swiftui-xflow-review`
- `update-swiftui-apis`

View File

@@ -2,7 +2,7 @@
type: current
project: fidelity
status: active
updated: 2026-05-01
updated: 2026-05-05
tags:
- current-work
- fidelity
@@ -15,10 +15,10 @@ tags:
- Track REST migration findings
- Debug Discourse and AO issues
- Prepare better updates for the current manager or stakeholder through Mattermost
- Follow up on active tickets through `project-knowledge/02-work-items/`, especially `PDIAP-15838` and `PDIAP-15836`
- Follow up on active tickets through `project-knowledge/02-work-items/`, especially branch maintenance for `PDIAP-15838` and implementation planning for `PDIAP-15836` / `PDIAP-12284`
- `PDIAP-15765` is done and `PDIAP-14859` is also done
- `PDIAP-15838` is the active Apollo-removal / REST-migration cleanup and validation focus
- `PDIAP-15836` comes after the current REST-investigation / Apollo-removal work
- `PDIAP-15838` is Done from a Jira/status perspective after external review feedback was addressed, but its draft PR must remain unmerged and kept current with `main` until REST backend production readiness and the required REST-toggle consumer validation window allow merge
- `PDIAP-15836` is now paired with `PDIAP-12284` for the UIKit-removal / pure SwiftUI lifecycle implementation path; Quy already moved both into next sprint `26Q2.6`, David can start work now, but leave Jira status in To Do and do not move either story to In Progress until Thursday
- Keep the separate `HybridBrokerageAccountOpening` / `JointIdentityCheck` scenario out of `PDIAP-15765` scope unless later evidence proves it belongs there
- Include feature-flag planning for the broader UIKit-removal spike, including dismissal sequencing changes that affect consumers
- Thoroughly verify current `ApexBridgingAddressComponent` / rule-loading usage before describing it as inactive or dead code
@@ -42,8 +42,8 @@ tags:
- Jeff suggested broadening the investigation support path while direct Flagship LaunchDarkly access is still missing: monitor the Tauf thread, follow up with Jeffrey O'Leary, package the scenario for the AI tool with build settings and tool details, and ask Aylwing for a quick perspective if available
- The Fidelity-side AI tool Jeff referenced for this investigation is GitHub Copilot
- Jeff later relayed that Adam says the latest build is now activating REST correctly, so David should switch back to the current Jira story work for removing GraphQL and related LaunchDarkly toggles
- `PDIAP-15838` draft PR is open for internal review; after internal review, send the link to Bruce
- Do not merge the GraphQL/Apollo removal PR until the previous REST-toggle implementation has been QA-tested and active in production with REST enabled for all consumers for 30 days without issues
- `PDIAP-15838` draft PR has reached external review; Bruce left minor feedback, David addressed it, and Jeff directed David to move the ticket to Done while holding the merge
- Do not merge the GraphQL/Apollo removal PR until REST backend is live in production and the previous REST-toggle implementation has been QA-tested and active in production with REST enabled for all consumers for at least 30 days without issues
- Current `PDIAP-15838` follow-up centers on the `PicoSDK` update in `SampleApp`: the newer Pico path removes the remaining transitive Apollo dependency, re-enables FGO and FidFolios testing in `SampleApp`, and aligns the sample implementation with current Fid4 usage
- The `PicoSDK` update affects `SampleApp`, not the `XFlowSDK` production runtime directly
- The new Discourse / FTTransfer AccountLink issue is under investigation; Zachary believes it may come from XFlow, but current evidence shows it reproduces in `FTTransferPlayground` with Zachary's account and does not reproduce in `Fid4` with the same account
@@ -53,6 +53,12 @@ tags:
- Deeper Discourse / FTTransfer analysis now points to presentation-layer SwiftUI identity/lifecycle churn around `BankInformationView` and `BankSetupWebView`: XFlow eventing appears to set shared consumer-observed state, but current evidence does not show it directly mutating view identity, host lifecycle, or alert state.
- The working non-XFlow route appears to avoid the issue because it bypasses the extra XFlow destination presentation layer and associated state-coupling surface, while the failing playground path keeps the alert/popup transition and cover lifecycle coupled in the same reactive chain.
- The next implementation direction for the Discourse / FTTransfer issue is a pure SwiftUI fix that decouples alert state from the cover identity chain, avoiding unnecessary UIKit dependencies
- `PDIAP-16167 - AccountLink - XFlow causing web view rewrites investigation` was created for the FTTransfer AccountLink investigation and root-cause report
- Include in the `PDIAP-16167` report that the issue persists when rolling back `XFlowSDK` to `v0.1.0`, predating REST and modern architecture changes; Jeff explicitly asked David to include this in the document
- `PDIAP-16167` is Done: the Confluence report was published, findings were sent to Zachary / Jira / Discourse, and future references should describe the root cause as a consumer-side SwiftUI presentation-topology issue in `BankInformationView`, not an XFlow/XFlowViewMaker regression
- `PDIAP-12284` is the original UIKit-wrapping removal story reopened after rollback; track `PDIAP-15836` as blocked by `PDIAP-12284` unless further validation proves the lifecycle fix can be implemented independently on the SwiftUI path
- After `PDIAP-15836` / `PDIAP-12284` implementation, expect a long-lived branch: Jeff's current planning assumption is that the GraphQL-removal branch merges first after the REST validation period, then that is merged into the UIKit-removal/lifecycle branch, with `PDIAP-15836` / `PDIAP-12284` merge around 90-100 days from 2026-05-05 unless Fidelity shortens the review periods
- Backlog triage found future/reference items: `PDIAP-11962` has earlier secret-scanning closure evidence but two Google API Key alerts remain; `PDIAP-11961` is the related unassigned rotation/invalidation story for those alerts; `PDIAP-11562` concerns XFlow podspec/Fid4 debug-build configuration; Sparta items `PDIAP-12226`, `PDIAP-12227`, and `PDIAP-12228` are lower-priority until XFlow backlog items that can be closed are handled
- Before closing out the AO thread, send one more working-group Teams reply that summarizes the original iOS issue, links the Jira comment, Discourse comment, and PR, and separates the remaining `HybridBrokerageAccountOpening` / `JointIdentityCheck` service-side issue
- The `HybridBrokerageAccountOpening` / `JointIdentityCheck` rule-content issue appears unchanged between QA and Production in Cogstore and should be treated as the remaining service-side follow-up
@@ -75,11 +81,13 @@ tags:
- Avoid treating GitHub Copilot or LaunchDarkly as story-specific tools; both are broader Fidelity workflow tools that happened to matter in this investigation
- Defining a consumer rollout plan for UIKit-removal sequencing changes, including validation, communication, and feature-flag retirement
- Keep Apollo-removal / REST-migration cleanup grounded in production readiness: source-level cleanup can continue, but merge/release timing depends on the prior REST-toggle implementation being QA-tested and stable in production for the agreed window
- Keep the GraphQL/Apollo removal branch and the future `PDIAP-15836` / `PDIAP-12284` branch current with `main`; if conflict resolution looks non-trivial, flag it so a 1-2 point branch-maintenance story can be created
- Avoiding assumptions when comparing iOS and Android validation behavior; scenario-specific parity needs to be confirmed before reporting scope
- Avoiding assumptions about legacy Apex/ApexKit paths; breakpoint evidence and helper usage both need to be reconciled before reporting ownership or replacement guidance
- When ownership is still uncertain under production pressure, prefer rollback-plus-investigation framing over confident blame assignment to consumers
- Swift 6 migration risk is now time-sensitive because external dependency removal could break XFlow before the planned `26Q3` work
- The write-up for Quy should remain the reference framing for moderate effort, medium risk, and required consumer validation while deeper implementation details are still being researched
- Remaining Google API Key alerts should not be framed as newly introduced REST-story secrets unless evidence changes; current evidence ties them to older April 18, 2025 work and a separate backend/rotation support path
---

View File

@@ -2,7 +2,7 @@
type: current-work-items
project: fidelity
status: active
updated: 2026-05-04
updated: 2026-05-05
tags:
- current-work
- work-item
@@ -20,8 +20,36 @@ Update the per-ticket files first when scope, status, sequencing, or communicati
- `PDIAP-15838` - Remove Apollo for iOS
Detail: `project-knowledge/02-work-items/pdiap-15838.md`
Current note: active Apollo-removal cleanup and validation; draft PR is open for internal review. `SampleApp` was updated to a newer `PicoSDK` path so Apollo is removed from the transitive sample-app dependency path too. Do not merge until the previous REST-toggle implementation has been QA-tested and active in production with REST enabled for all consumers for 30 days without issues.
Current note: ticket moved to Done after external review feedback was addressed, but the draft PR stays unmerged. Keep the branch up to date with `main` until REST backend is live in production and REST toggles have been enabled for consumers for the required validation window; expected merge timing is at least 30 days out.
- `PDIAP-15836` - Modernize dismissal delegate lifecycle sequencing for pure SwiftUI environment
Detail: `project-knowledge/02-work-items/pdiap-15836.md`
Current note: approved at `8` points, rooted in the AccountLink dismissal sequencing investigation, and sequenced after `PDIAP-15838`.
Current note: approved at `8` points and now paired with `PDIAP-12284` for the UIKit-removal implementation path. Quy already moved it into next sprint `26Q2.6`; leave it in To Do and do not move to In Progress until Thursday. Treat `PDIAP-15836` as blocked by `PDIAP-12284` unless validation proves the lifecycle fix can be implemented independently.
- `PDIAP-12284` - Remove UIKit wrapping from XFlow
Detail: `project-knowledge/02-work-items/pdiap-12284.md`
Current note: reopened after rollback and should be handled with `PDIAP-15836`. Quy already moved it into next sprint `26Q2.6`; work can begin now, but Jira status stays To Do until Thursday and merge/release waits until after REST-transition consumer validation.
## Backlog / Future Reference
- `PDIAP-11962` - Closure of secret scanning alerts
Detail: `project-knowledge/02-work-items/pdiap-11962.md`
Current note: prior closure was submitted on October 9, 2025 and Matthew closed earlier alerts/story on March 5, 2026. Two Google API Key alerts remain open and appear tied to old April 18, 2025 work, not the current REST story.
- `PDIAP-11961` - Remediation of Exposed Secrets in XFlow iOS SDK - Request for Rotation/Invalidation
Detail: `project-knowledge/02-work-items/pdiap-11961.md`
Current note: related unassigned story for remaining Google API Key alerts; not a current priority but should be preserved for future planning.
- `PDIAP-11562` - Investigate if XFlow is being built as debug
Detail: `project-knowledge/02-work-items/pdiap-11562.md`
Current note: likely tied to the `XFlowSDK_Debug` variable check in the XFlow podspec and Fid4 consumption, not Sparta-team work; historical Slack suggests Jenkins may build the xcframework path while local development consumes XFlow as a normal library, but this needs current validation.
- `PDIAP-12226`, `PDIAP-12227`, `PDIAP-12228` - Sparta backlog items
Details: `project-knowledge/02-work-items/pdiap-12226.md`, `project-knowledge/02-work-items/pdiap-12227.md`, `project-knowledge/02-work-items/pdiap-12228.md`
Current note: Slack history ties these to the SpartaSDK follow-up split from initialization/JSON decoding, grid rendering/core components, and interactive/lifecycle behavior. Decoding and rendering are partially complete; interactive components remain blocked by unresolved mobile JavaScript execution.
## Recently Completed
- `PDIAP-16167` - AccountLink - XFlow causing web view rewrites investigation
Detail: `project-knowledge/02-work-items/pdiap-16167.md`
Current note: moved to Done after publishing the Confluence report and sending the findings to Zachary / Jira / Discourse. Future references should frame this as a consumer-side SwiftUI presentation-topology issue, not an XFlow/XFlowViewMaker regression.

View File

@@ -1,7 +1,7 @@
---
type: work-item-index
project: fidelity
updated: 2026-04-16
updated: 2026-05-05
tags:
- work-item
- map
@@ -16,19 +16,39 @@ Provide a quick view of active and recently relevant Jira-linked work while keep
## Active
- [pdiap-14859.md](./pdiap-14859.md)
`PDIAP-14859` `Spike - Research strategy to remove final UIKit wrapping from XFlowSDK and XFlowViewMaker without disrupting consumer implementation` spike wrap-up work around dual UIKit/SwiftUI support, dynamic `UIHostingController` removal, consumer rollout planning, and linking the final result documents.
- [pdiap-15838.md](./pdiap-15838.md)
`PDIAP-15838` next story to work on; approved scope removes Apollo and GraphQL-specific iOS transport code while leaving REST.
`PDIAP-15838` ticket is Done, but the draft PR remains unmerged and must be kept current with `main` until REST backend production readiness and the required consumer validation window allow merge.
- [pdiap-15836.md](./pdiap-15836.md)
`PDIAP-15836` approved follow-up story for dismissal delegate lifecycle sequencing in pure SwiftUI; comes after `PDIAP-15838`.
`PDIAP-15836` approved follow-up story for dismissal delegate lifecycle sequencing in pure SwiftUI; paired with `PDIAP-12284` and should not move to In Progress until the next sprint starts.
## Active / Reopened
- [pdiap-12284.md](./pdiap-12284.md)
`PDIAP-12284` reopened original UIKit-wrapping removal story; current blocker/dependency path for `PDIAP-15836`.
## Backlog / Future Reference
- [pdiap-11962.md](./pdiap-11962.md)
`PDIAP-11962` closure of secret scanning alerts; prior closure was submitted/closed, but two Google API Key alerts remain.
- [pdiap-11961.md](./pdiap-11961.md)
`PDIAP-11961` related unassigned request for remaining Google API Key rotation/invalidation.
- [pdiap-11562.md](./pdiap-11562.md)
`PDIAP-11562` investigate whether XFlow is being built as debug; historical Slack ties this to the `XFlowSDK_Debug` podspec variable and Fid4/Jenkins consumption.
- [pdiap-12226.md](./pdiap-12226.md), [pdiap-12227.md](./pdiap-12227.md), [pdiap-12228.md](./pdiap-12228.md)
Sparta backlog items split across JSON decoding/initialization, grid rendering/core components, and interactive/lifecycle behavior; decoding/rendering are partially complete and interactive components remain blocked by unresolved mobile JavaScript execution.
## Recently Completed
- [pdiap-16167.md](./pdiap-16167.md)
`PDIAP-16167` AccountLink investigation completed with Confluence/Jira/Discourse/Zachary follow-up; root cause is a consumer-side SwiftUI presentation-topology issue, not XFlow/XFlowViewMaker.
- [pdiap-15765.md](./pdiap-15765.md)
`PDIAP-15765` authenticated-only DOB issue in `HybridYouthAccountOpening` / `TeenIdentityCheck`; reopened around the iOS-only handling gap while the separate cross-platform `HybridBrokerageAccountOpening` / `JointIdentityCheck` scenario stays out of scope.
`PDIAP-15765` authenticated-only DOB issue in `HybridYouthAccountOpening` / `TeenIdentityCheck`; completed while keeping the separate `HybridBrokerageAccountOpening` / `JointIdentityCheck` scenario out of scope.
- [pdiap-14859.md](./pdiap-14859.md)
`PDIAP-14859` spike around final UIKit wrapping removal and rollout planning is done.
---

View File

@@ -0,0 +1,41 @@
---
type: work-item
project: fidelity
status: backlog-review
ticket: PDIAP-11562
title: "Investigate if XFlow is being built as debug"
systems: [xflowsdk, fid4]
workstreams: [dependency-management, backlog-triage]
people: [jeff-dewitte]
related: []
updated: 2026-05-05
tags:
- work-item
- fidelity
- build
---
# PDIAP-11562 - Investigate if XFlow is being built as debug
## Status
- Backlog item under review for possible next work.
---
## Current Understanding
- This is related to how the XFlow podspec is configured and how Fid4 consumes it.
- It is not currently understood as Sparta-team work.
- The concern is whether a debug build configuration or debug-like flag is being used in a dependency-integration context where it should not be.
- Next investigation should identify why/how the flag or build configuration is used and whether there is a safer integration approach.
---
## Historical Slack Context
- September 2025 backlog context lists the full title as `Spike: Research/investigate if Xflow is being built as debug in Fid4 and if thats a concern or intentional.`
- November 2025 Slack context says the relevant check is the `XFlowSDK_Debug` variable in the podspec, not a Podfile setting.
- David confirmed in November 2025 that the `XFlowSDK_Debug` variable check was still present.
- Working interpretation from that thread: Jenkins likely does not set the variable when building the static framework; the `if/else` path may be intended so local development consumes XFlow as a normal library while Jenkins builds/consumes it as an xcframework.
- Treat that as a historical hypothesis to verify in current code/build settings, not as a confirmed current production behavior.

View File

@@ -0,0 +1,39 @@
---
type: work-item
project: fidelity
status: backlog
ticket: PDIAP-11961
title: "Remediation of Exposed Secrets in XFlow iOS SDK - Request for Rotation/Invalidation"
systems: [xflowsdk]
workstreams: [security, backlog-triage]
people: [jeff-dewitte]
related: [pdiap-11962]
updated: 2026-05-05
tags:
- work-item
- fidelity
- security
---
# PDIAP-11961 - Remediation of Exposed Secrets in XFlow iOS SDK - Request for Rotation/Invalidation
## Status
- Backlog item; not assigned yet.
- Jeff relayed that this is not a priority yet, but asked David to keep the details noted for future reference.
---
## Context
- Related to the remaining Google API Key alerts not included in the previous `PDIAP-11962` closure.
- If key rotation or invalidation is required, David/XFlow likely needs backend support or clarification because Google API Key rotation is not owned directly by the XFlow iOS side.
---
## Historical Slack Context
- October 2025 Slack context describes `PDIAP-11961` as the request for rotation/invalidation of active exposed Google API keys.
- The active Google API keys were documented as still valid/in use by the service, so they were intentionally separated from inactive-secret closure evidence.
- `PDIAP-11962` was created as the second-phase closure story to run after `PDIAP-11961` invalidation/rotation work completed.
- Earlier investigation noted that the API key appeared in a service response and that GitHub was flagging the old commit where the key had been hard-coded and later removed.

View File

@@ -0,0 +1,52 @@
---
type: work-item
project: fidelity
status: backlog-review
ticket: PDIAP-11962
title: "Closure of secret scanning alerts"
systems: [xflowsdk]
workstreams: [security, backlog-triage]
people: [jeff-dewitte]
related: [pdiap-11961]
updated: 2026-05-05
tags:
- work-item
- fidelity
- security
---
# PDIAP-11962 - Closure of secret scanning alerts
## Status
- Backlog item under review for future work.
- Earlier alert-closure process appears partially completed, but two Google API Key alerts remain open.
---
## Current Findings
- David found an October 9, 2025 email confirming the prior submission.
- Follow-up shows Matthew closed the earlier alerts/story on March 5, 2026.
- Two Google API Key alerts remain open and were not part of that closure.
- Those alerts appear tied to an old `MockPageViewWithHiddenToggle` commit from April 18, 2025, not newly introduced REST-story work.
- Google API Key rotation is not owned by David/XFlow directly; backend support or clarification may be needed if rotation/invalidating is required.
---
## Historical Slack Context
- October 2025 Slack context ties this story to `PDIAP-11573 - Remediate secret scanning alerts in XFlow iOS SDK`.
- The intended sequence was:
1. report inactive secrets through the SSDLC/AAVD process,
2. use `PDIAP-11961` to handle invalidation/rotation of still-active Google API keys,
3. use `PDIAP-11962` to close the GitHub alerts after `PDIAP-11961` is completed.
- Slack context from October 10, 2025 says inactive secrets were reported in `ESWR-35407`, `PDIAP-11961` was created for active-secret invalidation, and `PDIAP-11962` was created to manage alert closure after invalidation.
- Slack context from November 19, 2025 says the secret-remediation alerts were still present and none had been marked resolved at that time.
- Treat `PDIAP-11962` as the closure/follow-up story, not the rotation/invalidation story itself.
---
## Related Work
- `PDIAP-11961 - Remediation of Exposed Secrets in XFlow iOS SDK - Request for Rotation/Invalidation` is the related story for the remaining Google API Key alerts and is not assigned yet.

View File

@@ -0,0 +1,40 @@
---
type: work-item
project: fidelity
status: backlog-partial
ticket: PDIAP-12226
title: "iOS: Implement SpartaSDK initialization and JSON decoding"
systems: [sparta, xflowsdk]
workstreams: [sparta, backlog-triage]
people: [jeff-dewitte, aylwing-olivas]
related: [pdiap-12227, pdiap-12228]
updated: 2026-05-05
tags:
- work-item
- fidelity
- sparta
---
# PDIAP-12226 - iOS: Implement SpartaSDK initialization and JSON decoding
## Status
- Backlog item; partially complete.
---
## Current Understanding
- Last known work was a decoding-layer refactor based on internal feedback from Aylwing.
- Direction was to make decoding strict so malformed backend responses surface errors to the consumer instead of silently skipping unsupported components.
- Earlier approach used a `strict mode` toggle where unsupported components were omitted from rendering.
- Refactor is still in progress; if no new component types are added, it may not require much beyond the existing work.
---
## Historical Slack Context
- October 2025 Slack context shows the work started from `PDIAP-11956` / `PDIAP-12066` exploration: dynamic JSON decoding, `SpartaNodeRegistry`, strict-mode behavior, and fallback handling for unknown node types.
- By October 21, 2025, decoding tests validated fallback handling and registry lookups in an internal `SwiftUIBuilder` PR.
- November 2025 planning split the remaining SpartaSDK work into separate stories; this one became the initialization and JSON-decoding story.
- November 20-24, 2025 Slack context says `PDIAP-12226` was moved to a later sprint and David was reviewing whether the current JSON-decoding implementation was ready for a formal PR.

View File

@@ -0,0 +1,37 @@
---
type: work-item
project: fidelity
status: backlog-partial
ticket: PDIAP-12227
title: "iOS: Render grid-based layout and core visual components"
systems: [sparta, xflowsdk]
workstreams: [sparta, backlog-triage]
people: [jeff-dewitte]
related: [pdiap-12226, pdiap-12228]
updated: 2026-05-05
tags:
- work-item
- fidelity
- sparta
---
# PDIAP-12227 - iOS: Render grid-based layout and core visual components
## Status
- Backlog item; partially complete.
---
## Current Understanding
- There is already a working base that places elements on the grid layout.
---
## Historical Slack Context
- October 2025 Slack context shows rendering work began after the decoding spike, with a SwiftUI renderer/protocol path and initial support for titles, buttons, text, and grid-related components.
- The Sparta work uses JSON responses with grid-position attributes; Jeff advised avoiding the term `DSL` in user-facing/sample naming unless the team confirms that language.
- November 2025 planning split the work so `PDIAP-12227` covered grid-based layout and core visual components.
- November 20, 2025 Slack context says Quy wanted `PDIAP-12226` and `PDIAP-12227` placed into the sprint after next at that time, with the option to pull them in earlier if capacity allowed.

View File

@@ -0,0 +1,37 @@
---
type: work-item
project: fidelity
status: backlog-blocked
ticket: PDIAP-12228
title: "iOS: Implement interactive components and lifecycle behaviors"
systems: [sparta, xflowsdk]
workstreams: [sparta, backlog-triage]
people: [jeff-dewitte]
related: [pdiap-12226, pdiap-12227]
updated: 2026-05-05
tags:
- work-item
- fidelity
- sparta
---
# PDIAP-12228 - iOS: Implement interactive components and lifecycle behaviors
## Status
- Backlog item; blocked or unresolved.
---
## Current Understanding
- Covers interactive components such as buttons.
- Main unresolved question was how to execute JavaScript on mobile.
---
## Historical Slack Context
- November 2025 planning split the SpartaSDK proof-of-concept follow-up into initialization/decoding, rendering, interactive components/lifecycle, and navigation/flow logic tracks.
- Earlier Slack updates show buttons and dropdown rendering were already partially explored under foundational SpartaSDK work, but full interactive behavior and lifecycle/navigation behavior were not complete.
- Treat JavaScript execution on mobile as the major unresolved blocker for richer interactive behavior unless current project evidence supersedes it.

View File

@@ -0,0 +1,47 @@
---
type: work-item
project: fidelity
status: backlog-ready
ticket: PDIAP-12284
title: "Remove UIKit wrapping from XFlow"
systems: [xflowsdk, xflowviewmaker]
workstreams: [xflow-swiftui-migration, consumer-integration]
people: [jeff-dewitte]
related: [pdiap-15836, pdiap-15838]
updated: 2026-05-05
tags:
- work-item
- fidelity
- swiftui
- xflow
---
# PDIAP-12284 - Remove UIKit wrapping from XFlow
## Status
- Reopened after rollback.
- Quy already moved this story into the next sprint (`26Q2.6`); leave it in To Do until the sprint starts on Thursday.
- Jeff asked David to start working on this with `PDIAP-15836`, but not to move the active story to In Progress until Thursday.
---
## Context
- This is the original story for removing the UIKit wrapping.
- Current relationship to track: `PDIAP-15836` is blocked by this story because the lifecycle-sequencing fix depends on the UIKit removal landing, unless further validation proves part of `PDIAP-15836` can be implemented independently on the SwiftUI path.
---
## Historical Slack Context
- November 21, 2025 Slack context says David created `PDIAP-12284` and `PDIAP-12285` to cover remaining UIKit-removal work inside XFlow after reviewing open Sendable and XFlowViewMaker-track stories.
- That same backlog refinement closed out pending XFlowViewMaker stories that were no longer needed.
- Current Mattermost context supersedes the old standalone refinement framing: this story is now reopened after rollback and should be handled together with `PDIAP-15836`.
---
## Sequencing
- Work can begin, but merge/release should wait until the REST-transition consumer-validation window has completed.
- Keep the implementation branch up to date with `main` while waiting for approval to work with consumers and merge.

View File

@@ -1,14 +1,14 @@
---
type: work-item
project: fidelity
status: active
status: backlog-ready
ticket: PDIAP-15836
title: "Modernize dismissal delegate lifecycle sequencing for pure SwiftUI environment"
systems: [xflowsdk, xflowviewmaker, ftframeworks]
workstreams: [xflow-swiftui-migration, consumer-integration]
people: [jeff-dewitte]
related: [pdiap-14859]
updated: 2026-04-21
related: [pdiap-14859, pdiap-12284, pdiap-15838]
updated: 2026-05-05
tags:
- work-item
- fidelity
@@ -19,8 +19,10 @@ tags:
## Status
- Approved
- Sequenced after `PDIAP-15838`
- Approved, but should not be moved to In Progress until the next sprint starts
- Quy already moved this story into the next sprint (`26Q2.6`); leave it in To Do until the sprint starts on Thursday
- Jeff confirmed David can start the actual implementation work now, but must not move the story to In Progress until Thursday
- Sequenced after `PDIAP-15838` source work, but merge/release is delayed until after REST-transition consumer validation
- Sized at `8` points
---
@@ -44,8 +46,11 @@ tags:
## Sequencing And Dependencies
- This story should come after `PDIAP-15838`.
- `PDIAP-12284` is the original UIKit-wrapping removal story and was reopened after rollback.
- Current relationship to add/track in Jira: `PDIAP-15836` is blocked by `PDIAP-12284`, because the UIKit removal needs to land for the lifecycle fix to apply. David still needs to validate whether any part of `PDIAP-15836` can be implemented independently on the SwiftUI path.
- It is aligned with epic `26Q2 - Updating XFlowSDK to Decouple and Fix ApexKit Dependencies (Split Part 2)`.
- If possible, it should use the same consumer-impact feature flag strategy as the broader UIKit-removal rollout.
- Expect a long-lived branch: after implementation, maintain the branch until consumer-testing approval. Jeff expects the GraphQL-removal branch to merge first after the REST validation period, then that branch should be merged into the `PDIAP-15836` / `PDIAP-12284` branch. Current estimate is roughly 90-100 days from 2026-05-05 unless Fidelity shortens the review windows.
---
@@ -56,3 +61,4 @@ tags:
- The Confluence/root-cause document was updated to reflect that FTTransfer changes are not the primary need anymore.
- The primary recommendation is to adjust the dismissal handling/sequencing correctly in the hosting path.
- FTTransfer improvements can still be mentioned as a secondary improvement, but not as a required change to reproduce the same visual behavior.
- When explaining why code still remains, clarify that the spike identified and documented the root cause, but implementation changes have not yet been published.

View File

@@ -1,14 +1,14 @@
---
type: work-item
project: fidelity
status: active
status: done-pending-merge
ticket: PDIAP-15838
title: "Remove Apollo for iOS"
systems: [xflowsdk]
workstreams: [rest-migration]
people: [jeff-dewitte, bruce-meeks, adam-abdelhadi, tauf, jeffrey-oleary, aylwing-olivas]
related: [launchdarkly, github-copilot]
updated: 2026-04-29
updated: 2026-05-05
tags:
- work-item
- fidelity
@@ -19,8 +19,9 @@ tags:
## Status
- Draft PR open for internal review
- PR merge should wait until the previous REST-toggle implementation has been QA-tested and active in production with REST enabled for all consumers for 30 days without issues
- Ticket moved to Done after external review feedback was addressed
- Draft PR remains unmerged and must be kept up to date with `main`
- PR merge should wait until REST backend is live in production and the previous REST-toggle implementation has been QA-tested and active in production with REST enabled for all consumers for at least 30 days without issues
- Sized at `8` points
---
@@ -82,9 +83,15 @@ tags:
- Bruce asked whether iOS Fid4 has a release-build optimization or code-minification concept comparable to Android; treat this as a validation/build-configuration question until clarified, not as evidence of a known iOS minification issue.
- Jeff clarified the validation ask: inspect whether Fid4 has simulator-versus-physical-device or generated-build differences in build settings/schemes/configurations, including any optimized-build-size or release-style settings that could explain behavior seen in generated builds but not when running locally.
- Current likely Fid4 build differences to report: Trunk/generated builds use the `Release` configuration while local runs are usually `Debug`; optimization settings such as `SWIFT_OPTIMIZATION_LEVEL` and `GCC_OPTIMIZATION_LEVEL` can differ; Jenkins uses a generated `build-overrides` xcconfig that local builds do not use and may affect values such as secrets; and CocoaPods dependency resolution can vary depending on the local specs repo state.
- External review reached Bruce and produced minor feedback. David addressed the feedback and pushed the suggested change.
- One accepted review change was to set `responseKey: String? = nil` as the default in `FlowRESTOperationContract`, allowing operations such as `updateSlots`, `storeString`, and `publishEvent` to omit `responseKey` when not needed.
- The native Swift domain enum file should remain as the canonical location for XFlow domain enums after removal of GraphQL-generated code.
- Jeff directed David to move the ticket to Done, while keeping the PR unmerged for at least 30 days.
- Branch maintenance is now part of the work: keep the GraphQL/Apollo-removal branch up to date with `main` until the REST backend/toggle validation window allows merge. If future `main` merges create conflicts that look non-trivial, raise it so a 1-2 point maintenance story can be created.
---
## Sequencing
- This story remains sequenced before `PDIAP-15836`.
- This branch should merge to `main` before the future `PDIAP-15836` / `PDIAP-12284` branch is updated and merged.

View File

@@ -1,7 +1,7 @@
---
type: work-item
project: fidelity
status: active
status: done
ticket: PDIAP-16167
title: AccountLink - XFlow causing web view rewrites investigation
systems: [xflowsdk, xflowviewmaker, fttransfer]
@@ -13,16 +13,16 @@ tags:
- fidelity
- discourse
- swiftui
updated: 2026-05-04
updated: 2026-05-05
---
# PDIAP-16167 - AccountLink - XFlow causing web view rewrites investigation
## Status
- Root cause identified and verified
- Confluence report requested by Jeff; draft sent for review
- Jeff approved creating the story
- Done
- Confluence report published
- Findings/comment sent to Zachary and posted for Jira/Discourse follow-up
---
@@ -51,11 +51,12 @@ updated: 2026-05-04
## Current Guidance
- Jeff's direction: document the findings clearly in a Confluence report, send it to Zachary, and comment it on the story. No need to fix their code directly; clear communication of the issue is the goal.
- Jeff also asked to include a version comparison showing that recent REST/GraphQL changes to XFlowSDK do not intersect with this flow.
- Keep future references clear that this was documented as a consumer-side SwiftUI presentation-topology defect, not an XFlow/XFlowViewMaker regression.
- Include Jeff's preferred clarification that `XFlowSDK v0.1.0` predates the REST and Apollo-related changes that were newer additions.
---
## Next Step
## Closure Notes
- Finalize and publish the Confluence report with all findings, the v0.1.0 rollback evidence, and the XFlowViewMaker version comparison.
- The published recommendation is to move the full-screen cover modifier to the stable root of `BankInformationView`, outside the conditional branch.
- David moved the story to Done on 2026-05-05.

View File

@@ -1,10 +1,10 @@
---
type: daily
project: fidelity
date: 2026-05-04
date: 2026-05-01
status: active
focus: []
work-items: []
focus: [ao-discourse, xflow-debugging]
work-items: [pdiap-16167]
blockers: []
tags:
- daily
@@ -12,35 +12,41 @@ tags:
updated: 2026-05-04
---
# 2026-05-04
# 2026-05-01
## Focus
-
- Verify and document the root cause for the FTTransfer AccountLink web-view reload issue.
---
## Work Done
-
- Created `PDIAP-16167 - AccountLink - XFlow causing web view rewrites investigation`.
- Prepared the root-cause report for the FTTransfer AccountLink issue.
- Verified that XFlow eventing does not appear to be the direct cause of the reload.
- Verified that the issue persists when rolling back `XFlowSDK` to `v0.1.0`, which predates REST and modern architecture changes.
- Identified a minimal presentation-anchor change that resolves the alert auto-dismiss and web-view reload behavior.
---
## Findings
-
- Current evidence points to a consumer SwiftUI presentation-layer issue rather than recent XFlowSDK or XFlowViewMaker changes.
- The rollback-to-`XFlowSDK v0.1.0` finding should be included in the report because it helps separate the issue from recent XFlow changes.
---
## Communication
-
- Jeff asked David to put the findings into a Confluence report, share it with Zachary, and comment it on the story.
- Jeff specifically asked David to include the XFlowSDK version / rollback evidence in the report.
---
## Next Steps
-
- Finalize and share the root-cause report with the rollback evidence and minimal fix note.
---

View File

@@ -0,0 +1,51 @@
---
type: daily
project: fidelity
date: 2026-05-05
updated: 2026-05-05
focus: [pdiap-15838, pdiap-16167, pdiap-15836, backlog-triage]
work-items: [PDIAP-15838, PDIAP-16167, PDIAP-15836, PDIAP-12284, PDIAP-11962, PDIAP-11961, PDIAP-11562, PDIAP-12226, PDIAP-12227, PDIAP-12228]
blockers: [consumer-validation-window, backend-rest-production-readiness, remaining-google-api-key-alerts]
tags:
- daily
- fidelity
---
# 2026-05-05
## Mattermost Evidence Promoted
- `PDIAP-16167 - AccountLink - XFlow causing web view rewrites investigation`
- Daily scrum reported minor Confluence report adjustments and planned publication.
- The Confluence report was published and the proposed Jira/Discourse/DM wording was sent to Zachary.
- Final external framing: root cause is a consumer-side SwiftUI presentation-topology / view-identity invalidation in `BankInformationView`, not XFlow or XFlowViewMaker. The issue reproduces on `XFlowSDK v0.1.0`, predating REST and Apollo-related changes, and Flagship does not appear to show the same behavior because presentation ownership is behind a more stable boundary.
- David moved `PDIAP-16167` to Done.
- `PDIAP-15838 - Remove Apollo for iOS`
- Daily scrum reported the draft PR was sent for external review.
- Bruce left minor feedback; David addressed it and pushed the suggested change.
- One review change set `responseKey: String? = nil` as the default in `FlowRESTOperationContract`, so operations such as `updateSlots`, `storeString`, and `publishEvent` can omit `responseKey` when not needed.
- David kept the file that now serves as the canonical location for XFlow domain enums after removal of GraphQL-generated code.
- Jeff directed David to move the ticket to Done, while keeping the PR unmerged for at least 30 days.
- Jeff clarified that the GraphQL-removal branch must stay up to date with `main` until REST backend is live in production with REST toggles enabled and the 30-day validation window is complete.
- `PDIAP-15836 - Modernize dismissal delegate lifecycle sequencing for pure SwiftUI environment` and `PDIAP-12284`
- Jeff initially noted that starting this work now could create a long-lived branch, because UIKit-removal work needs feature flags, consumer testing, and a later merge/release window after the REST transition finishes.
- David clarified that the spike identified and documented the root cause, but no code changes have been published yet.
- `PDIAP-12284` is the original UIKit-wrapping removal story and was reopened after rollback. David noted `PDIAP-15836` should be treated as blocked by `PDIAP-12284`, although the Jira link was not yet present.
- Jeff later asked David to start working on `PDIAP-15836` / `PDIAP-12284`, but not to move the stories to In Progress until the next sprint starts on Thursday.
- Quy had already moved the stories into the next sprint (`26Q2.6`); David will leave them in To Do until the sprint starts.
- Jeff's branch-management guidance: after implementation, maintain the branch until consumer-testing approval; merge the GraphQL-removal branch first after the REST validation period, then merge that into the `PDIAP-15836` / `PDIAP-12284` branch. Expected merge timing is roughly 90-100 days from today unless Fidelity shortens the review windows.
- Backlog triage
- Jeff asked for previously assigned backlog work because there are no other in-progress stories after `PDIAP-16167` and `PDIAP-15838` move to Done.
- `PDIAP-11962 - Closure of secret scanning alerts`: David found an October 9, 2025 email confirming submission; Matthew closed the earlier alerts/story on March 5, 2026. Two Google API Key alerts remain open and were not part of that closure.
- `PDIAP-11961 - Remediation of Exposed Secrets in XFlow iOS SDK - Request for Rotation/Invalidation`: related story for the remaining Google API Key alerts; not assigned yet. Jeff said this is not a priority yet but should be noted for future.
- `PDIAP-11562 - investigate if XFlow is being built as debug`: David identified it as related to XFlow podspec configuration and Fid4 consumption, not Sparta-team work.
- Sparta backlog notes: `PDIAP-12226` decoding is partially complete with a strict-decoding refactor still in progress; `PDIAP-12227` rendering has a working grid-layout base and is partially done; `PDIAP-12228` interactive components is blocked by unresolved mobile JavaScript execution.
## Slack Archive Backfill
- Checked the historical Slack archive for the newly recreated work-item notes.
- Promoted useful Slack backfill into the relevant work-item notes for `PDIAP-11962`, `PDIAP-11961`, `PDIAP-11562`, `PDIAP-12226`, `PDIAP-12227`, `PDIAP-12228`, and `PDIAP-12284`.
- Skipped non-Fidelity API-key hits and generic Sparta chatter that did not map cleanly to these Jira items.

View File

@@ -1,7 +1,7 @@
---
type: daily-index
project: fidelity
updated: 2026-05-01
updated: 2026-05-05
tags:
- daily
- map
@@ -29,6 +29,7 @@ Promote durable facts into `project-knowledge/01-current/`, `project-knowledge/0
- [2026-04-28](2026-04-28.md)
- [2026-04-29](2026-04-29.md)
- [2026-04-30](2026-04-30.md)
- [2026-05-05](2026-05-05.md)
---

View File

@@ -4,6 +4,21 @@ Use `project-knowledge/01-current/current-work.md`, `project-knowledge/01-curren
Generate a standup update for the active project profile.
## Required refresh
- At the start of the day, fetch Mattermost before drafting.
- Fetch both latest available messages and previous-workday activity when the connector supports both modes.
- If Mattermost refresh fails, say so internally and use only saved workspace memory with clear caution; do not invent fresher context.
- Do not skip communication refresh for standup just to reduce latency, because stale standups cost more time to correct later.
## Temporal grounding
- Use the injected `Temporal Context` block as the source of truth for today's date, weekday, calendar yesterday, and default previous workday.
- Resolve relative terms before drafting: `today` means the injected `today`; `yesterday` means the injected `calendar_yesterday`; `previous workday` means the injected `default_previous_workday` unless refreshed Mattermost evidence found a later prior day with activity.
- For a Tuesday report, the previous-work section normally describes Monday's work.
- Do not infer dates from model memory, conversation history, or file modification times when the injected temporal context is available.
- If a requested report date conflicts with the injected current date, state the exact date being used before drafting.
## Output contract
- Use the greeting required by the active profile or command. If no greeting is specified, omit the greeting and start with the previous-work section.