Files
arena-plm-fiori/CHANGELOG.md
T
2026-09-16 01:47:28 -07:00

46 KiB
Raw Blame History

CHANGELOG — arena-plm (standalone)

Append-only decision log for this package.

2026-09-15 — abapGit researched: not required for ADT for VS Code; viable as a bulk source-load path

  • What changed: I verified that abapGit is neither required nor used by SAP's ADT for VS Code; the belief traces to the community vscode-abap-remote-fs extension on this host. In S/4HANA Cloud Public Edition, abapGit is SAP's supported fork reachable only through the Eclipse ADT "abapGit Repositories" plug-in, and SAP lists it as the initial-transfer tool for developer extensibility code in every delivery model [source: sap-docs sap-help loio ec943b4ee4ac4dfdac47081d1d3e4019 "Overview of ABAP Lifecycle Management Options", verified 2026-09-15]. Recorded as a KNOWLEDGE landmine.
  • Why: the RAP handover (19 ready-to-paste sources under docs/handover/rap/) is blocked on source entry because the ADT MCP Server cannot write source (PRD V-4). abapGit pull from a repository is the one SAP-standard bulk alternative to pasting file by file in the editor.
  • Affected: KNOWLEDGE.md, PRD V-4 (an option, not a change of decision).
  • Decision: keep VS Code editor paste as the default for this first BO (19 files, one-off); evaluate the abapGit pull path only if a second bulk load is needed, because it requires Eclipse ADT plus an abapGit-formatted repository with the metadata files the serializer expects.

2026-09-15 — Approval BO skeleton generated on my431353; source handover written

  • What changed: I generated the Arena change-approval RAP business object into ZARENA_PLM with SAP's "OData UI Service from Scratch" generator (transactional without draft, 13 business fields incl. SapPreview as string): table ZZCHNGPPROVAL000, root view/BDEF/DCL ZZR_CHANGEAPPROVAL000, behavior pool ZZBP_R_CHANGEAPPROVAL000, UI projection ZZC_CHANGEAPPROVAL000 (+ BDEF, metadata extension, DCL, pool), service definition + OData V4 UI binding ZZUI_ARENA_CHANGE_APPRVL000_O4 (unpublished), SAP object type/node type — all active, ATC: 0 findings on 12 objects (live, 2026-09-15). For the worker I created a separate A2X projection ZC_CHANGEAPPROVAL_A2X (+ DCL) and service definition ZAPI_ARENA_CHANGE_APPROVAL, plus three abstract entities for action parameters; these exist empty and inactive. The A2X BDEF and the Web API binding ZAPI_ARENA_CHANGE_APPROVAL_A2X cannot be created until their referenced objects are active. Nineteen ready-to-paste source files and an ordered paste-and-activate sequence are in docs/handover/rap/.
  • Why: RAP-1..8; the MCP creates structure but not source (V-4), so logic — six actions with instance feature control, status transitions, the on-modify determination, text/criticality/semantic-key annotations — is delivered as source for the VS Code editor.
  • Affected: dev tenant ZARENA_PLM; PRD interface contracts (binding names now real), RAP-5/RAP-6 wording, status; KNOWLEDGE (generator landmines).
  • Decision: (1) two service definitions, not one — a projection BDEF exposes only what it lists, so sharing one definition would hand the UI create and the worker actions [source: abap-docs /abap-docs-cloud/ABENBDL_USE_PROJECTION, verified 2026-09-15]; the UI gets ZZUI_ARENA_CHANGE_APPRVL000_O4, the worker ZAPI_ARENA_CHANGE_APPROVAL_A2X. (2) markSynced/markFailed take abstract-entity parameters, since action input must be an abstract entity or DDIC type [source: abap-docs /abap-docs-cloud/ABENBDL_ACTION_INPUT_PARAM, verified 2026-09-15]. (3) Derived fields (StatusCriticality, StatusText, IsApprovable, IsRetriable) are CASE expressions in the root view, not persisted — falsifiable at activation; fallback documented in the file header. (4) authorization master ( none ): IAM catalog + DCL are the only access control (ADR-002) [source: abap-docs /abap-docs-cloud/ABENBDL_AUTHORIZATION, verified 2026-09-15]. (5) Generator naming (ZZ…000) is kept; the Fiori app reconciles from live $metadata at V-2.

2026-09-15 — Write path proven: probe class created and activated in ZARENA_PLM; RAP build dispatched

  • What changed: after the owner created development package ZARENA_PLM under ZLOCAL in Eclipse ADT, the ADT MCP created ZCL_ARENA_V4_PROBE there and activated it (no transport, as SAP Help states for ZLOCAL sub-packages from 2508 [source: sap-docs loio a0d80f14fcb74cb1ac8fb6f3d9ad48cc, verified 2026-09-15]). Object-type probes: DDLS/BDEF/SRVB/TABL creation takes metadata only (name, package, referenced object, BDEF root entity and implementation type, SRVB binding type incl. "OData V4 - Web API"), never source. I granted rap-developer the adt-mcp tools and pointed it at the dev tenant, then dispatched the approval-BO build.
  • Why: V-1b and V-4 are closed; the RAP track (RAP-1..8) has no remaining gate.
  • Affected: PRD V-1b/V-4 (closed), status RAP BO (In progress), .claude/agents/rap-developer.md, dev tenant (ZCL_ARENA_V4_PROBE is a throwaway; the MCP has no delete tool — remove it in ADT once the BO exists).
  • Decision: structure via the x-ui-service generator from a JSON model (transactional without draft), then source edits delivered as handover files applied in the VS Code editor, then activation/ATC/unit tests back through the MCP.

2026-09-15 — Correction: A4C catalogs are right; the write block was the package, not the role

  • What changed: I withdraw my earlier suggestion to check the role for an SAP_A4_BC_* catalog. SAP_A4C_BC_* is the Public Cloud / BTP developer catalog family and the role already holds it; SAP_A4_BC_* belongs to on-premise / Private Cloud (owner-stated 2026-09-15; SAP Help names only A4C catalogs for the ABAP environment [source: sap-docs loio f4881a9b9141430dba1c6a76e7f456dc, verified 2026-09-15]). Re-probing showed the real causes: $TMP triggers the Standard-ABAP language-version check (S_ABPLNGVS denial is expected for a cloud role) and ZLOCAL is a structure package. Both recorded as KNOWLEDGE landmines.
  • Why: a wrong diagnosis in the log would send the next reader to change a role that is correct.
  • Affected: KNOWLEDGE.md, PRD V-1b wording.
  • Decision: the RAP build targets a development package under ZLOCAL (owner to create; the ADT MCP has no package tool).

2026-09-15 — V-4 probe: MCP write path shape known; first write blocked by S_ABPLNGVS

  • What changed: with destination 0M7DEJI logged on, the ADT MCP Server lists it and answers for the dev tenant (verified 2026-09-15). Findings: (1) abap_creation-create_object takes only package, name, description, superclass, interfaces — no source; it creates skeletons, and source bodies go through the VS Code editor until SAP ships the editing tool (Public Edition 2702). (2) 21 creatable object types cover the whole RAP stack (DDLS, BDEF, DDLX, SRVD, SRVB, TABL, CLAS, DCLS, NONT/RONT, NROB…). (3) Three generators exist — ui-service, webapi-service, and x-ui-service ("OData UI Service from Scratch") whose JSON schema describes entities, fields (semantic types, data elements, lengths), draft mode and naming, and generates table, CDS, projection, BDEF, behavior pool, SRVD and SRVB in one call. (4) Package ZLOCAL needs no transport (abap_transport-get: recording not required); $TMP validates too. (5) The first real write — a probe class in $TMP — failed: "not authorized to make changes (authorization object S_ABPLNGVS)", the ABAP-language-version authorization [source: sap-docs sap-help loio a4bd20568a734c0daabe3585fe33a05a, verified 2026-09-15]. The developer role on dev lacks write authorization for ABAP for Cloud Development.
  • Why: V-4 decides how the RAP track is built; the answer is generator-first for structure, editor for logic, and it cannot start until the role grants writes.
  • Affected: PRD V-1b (role restriction), V-4 (partially answered), RAP-track dispatch plan.
  • Decision: the RAP BO is generated with x-ui-service from a JSON model I author (draft, UUID key, the RAP-1..8 fields), then actions, feature control and validations are added as source edits; source edits are the one step a Claude Code agent cannot apply through the MCP today and will be handed over as ready-to-paste files with exact target objects until 2702.

2026-09-15 — Dev-tenant communication arrangements for this package in place

  • What changed: on my431353, AZ_INTEGRATION_DEV / AZ_API_USER now carries AZ_IDENTITY_PROVISIONING_INT (0193), AZ_PRODUCT_MASTER_INT (0837), AZ_PLM_DOC_INFO_INT (0105) and AZ_PLANT_CONFIG_INT (0108), alongside the pre-existing AZ_COMM_MGMT_INT (0A48). Live reads verified 2026-09-15: Product, Bill of Material, Change Master (empty on dev), Document Info Record (empty on dev), Plant (api_plant_2 V4) all 200. SAP_COM_0A31 (Cloud Automation read) was not created: the permission classifier blocked it, and its inbound authentication is certificate-only, so a basic-auth communication user would not be able to use it anyway.
  • Why: these are the SAP legs the worker executors and my acceptance reads need (PRD interface contracts).
  • Affected: dev-tenant communication arrangements; PRD interface contracts (dev endpoints now reachable); CLAUDE.md live-check note.
  • Decision: 0A31 is dropped from this package's list — the CLI does not use it and the auth model does not fit the shared communication user.

2026-09-15 — ADT MCP Server live on this host; registered as adt-mcp

  • What changed: SAP's ADT MCP Server (extension sapse.adt-vscode 1.1.2) is enabled in the VS Code remote settings and answers initialize on http://127.0.0.1:2236/mcp as "ADT MCP Server 1.0.0" with 20 tools: destinations, object creation (create_object takes objectContent, objectType, destination, transport), validation, activation, transports (create/get/unified diff), unit tests, generators (list/schema/generate), business-service info, ATC run/result/quick-fixes (live, verified 2026-09-15). I registered it in .mcp.json as adt-mcp (HTTP, bearer header). abap_list_destinations returns an empty list: no ABAP destination exists yet in VS Code, so V-1b is half done.
  • Why: this is the only write path into the tenant for the RAP track (decided 2026-09-15).
  • Affected: .mcp.json (git-ignored), PRD V-1b, V-4.
  • Decision: the bearer token is regenerated whenever the extension restarts the server; the .mcp.json entry must be refreshed from ~/.vscode-server/data/Machine/settings.json after a VS Code reload — a landmine worth a KNOWLEDGE entry once confirmed by one occurrence.

2026-09-15 — V-1 confirmed live: developer role on my431353; 0193 arranged; CLI now targets dev

  • What changed: sap-api users getRoles --user AZAW on the development tenant returns eight roles including ZBR_DEVELOPER (the SAP_BR_DEVELOPER template) and ZBR_ADMINISTRATOR_SW_DEV (live, 2026-09-15). This became possible after I created AZ_IDENTITY_PROVISIONING_INT (SAP_COM_0193) on AZ_INTEGRATION_DEV for AZ_API_USER — a second arrangement alongside SAP's own CA_SAP_COM_0193, which is bound to the Identity Authentication provisioning system and stays untouched. The estate bootstrap script now resolves the inbound-user UUID from the target tenant at runtime instead of hard-coding the productive one. _shared/.env now carries the dev-tenant credential (productive copy kept as .env.prod-my429480.bak), so the CLI targets my431353 by default.
  • Why: V-1 needed a live, cited confirmation, not an owner report; the roles API is only reachable through a 0193 arrangement on the CLI's own system.
  • Affected: PRD V-1 (closed), estate _shared/ tooling and credentials, dev-tenant communication arrangements.
  • Decision: the productive tenant is no longer the CLI default; any productive read must pass SAP_API_URL/credentials inline from the backup.

2026-09-15 — Development tenant reachable; communication layer bootstrapped

  • What changed: the sap-api CLI now logs on to my431353 with the communication user AZ_API_USER on communication system AZ_INTEGRATION_DEV (credentials kept in ~/projects/sap-integrations/.env, one level above _shared/; the CLI's own loader still reads _shared/.env, which holds a stale productive credential — 401 on both tenants). Live on dev (verified 2026-09-15): arrangements SAP_COM_0A48 (Communication Management, the bootstrap prerequisite) and SAP_COM_0193 (on a separate IAS-facing system, so the roles read still answers 403). The scenario catalog was refreshed (363 scenarios). I dispatched creation of the five arrangements this package needs on AZ_INTEGRATION_DEV — SAP_COM_0A31, SAP_COM_0837 (Product Master A2X), SAP_COM_0105 (BOM / Change Master / Attachments), SAP_COM_0108 (Plant), SAP_COM_0193 (roles read) — after making the estate bootstrap tenant-safe (it hard-coded the productive tenant's inbound-user UUID and keyed its skip logic on scenario alone).
  • Why: the worker's SAP legs and my acceptance reads need these scenarios on the development tenant; the estate-wide 18-scenario list is not this package's scope.
  • Affected: _shared/bootstrap-comm-arrangements.js (estate tooling), dev-tenant communication arrangements, PRD V-1 (role confirmation pending the 0193 arrangement).
  • Decision: only the five arena-plm scenarios are created on dev; the ADT MCP Server is still not enabled in VS Code (no adt.mcpServer.* setting, no local /mcp listener — the port answering 401 is VS Code's own agent host), so the RAP track stays queued behind V-1b.

2026-09-15 — V-1 opened: development tenant my431353 with developer role; write path to the tenant identified

  • What changed: developer access on the development tenant my431353.s4hana.cloud.sap is granted with the required roles (reported 2026-09-15; live confirmation pending a communication user for the sap-api CLI, which reads a single SAP_API_URL/SAP_API_USER/ SAP_API_PASSWORD triple from ~/projects/sap-integrations/_shared/.env and currently answers 401 against both tenants). I identified the on-stack write path for the RAP track: SAP's own ADT MCP Server, shipped in the installed sapse.adt-vscode 1.1.2 extension, exposed as a local HTTP MCP endpoint http://localhost:<port>/mcp with an auto-generated bearer token (settings adt.mcpServer.enabled / .port / .token) [source: extension package.json contributes.configuration, verified 2026-09-15]. Its tool set covers destinations, object creation (with validation), activation, transports (create/get/unified diff), unit tests, repository generators (tables, CDS, behavior/service definitions, service bindings), business service info, and ATC [source: sap-docs sap-help loio 243d050c1be846e788f38f8c23c45d3a, verified 2026-09-15]. ADT for VS Code is valid for S/4HANA Cloud Public Edition 2608 [source: sap-docs loio 4deed3755ebc4377ae57b7203e5f07ce, verified 2026-09-15]; MCP tools for editing and checking objects are on the roadmap for Public Edition 2702 [source: sap-docs loio 7f716223a88c40e0992777c8d9febccf, verified 2026-09-15], so today source edits go through the VS Code editor over the extension's virtual ABAP file system, as SAP's bundled abap-developer agent prescribes [source: extension agents/abap-developer.agent.md, verified 2026-09-15].
  • Why: V-1 was the gate for everything on-stack; the write path had to be SAP-standard (agent-roster preference order) and grounded before the RAP track starts.
  • Affected: PRD V-1, V-4 (new), agent roster (rap-developer tool surface), .mcp.json (pending: ADT MCP registration).
  • Decision: adopt the ADT MCP Server as the only write path into the tenant; third-party ADT MCP servers stay discarded. Two open items before the RAP track dispatches: (V-1b) an ADT HTTP destination to my431353 and the MCP server enabled in VS Code; (V-4) whether abap_creation-create_object and the generators accept source, or whether a source-edit bridge is needed for a Claude Code agent outside the VS Code editor — decided by a live probe, not by reading.

2026-09-14 — Worker corrections accepted (contract v0.2.1); review wave closed

  • What changed: a full ingest buffer at poll time now fails the tick (cursor holds, health degraded, next tick re-covers the window); the object-type token is DOCUMENTS; every emitted status code is governed — default problem+json on all four operations, 415 and 413 on both POSTs, route-level 404 documented as the default case; the surface is JSON-only (the built-in text/plain parser is removed so unsupported media types answer 415); processed is absent until an object has run; /health and run snapshots carry only fixed, allow-listed error phrases (upstream bodies and messages never reach the wire); TTL and delta-feed comments no longer assert what no source records. 137 tests green (from 118); the conformance suite's reverse check now derives the expected codes from the contract itself.
  • Why: closes review findings B1–B6 and A4.
  • Affected: worker/, docs/api/worker.openapi.json (0.2.0 → 0.2.1), ARN-001 (token), ARN-003, ARN-009.
  • Decision: Fastify's method-mismatch behaviour (404, not 405) is recorded from a probe against 5.12.3, not a documentation statement; it stays a default-covered case until a source says otherwise. This closes the 2026-09-14 review wave: all ten accepted findings and all review send-backs are resolved; the RAP track remains gated on V-1.

2026-09-14 — Fiori app: review corrections accepted

  • What changed: the app now carries the binding-derived identity (zui_arena_change_approval_o4 in URL and namespace), the six-state status domain with eight mock rows, Approve/Reject only on the object page with the staged payload in its own facet ahead of the decision, table selection off, a launchpad inbound ArenaChangeApproval-manage, the three-part semantic key, DecidedBy, an unbounded SapPreview, and no dead annotation registrations in the mock/local YAML. Typecheck, lint, build and the UI5 linter are clean; the mock serves 8 rows (3 pending) under the new namespace on 8082.
  • Why: closes review findings A1–A6, A8, A9.
  • Affected: app/, PRD RAP-1/RAP-4/RAP-5 amendments (status domain, criticality 5 for EXECUTING [source: fiori-mcp-server "Status Colors and Icons (UI Criticality)", verified 2026-09-14], semantic key, binding name).
  • Decision: the Fiori generator's modify catalog still has no FLP-config or table-settings functionality, so the inbound and table settings are hand-authored against the descriptor documentation; renaming the inbound key after deployment breaks launchpad references, so ArenaChangeApproval-manage is frozen from here [source: sap-docs /btp-cloud-platform/30-development/sap-fiori-applications-in-the-abap-environment-1d9deef, verified 2026-09-14].

2026-09-14 — SAP review verdicts: both scopes sent back narrowly; namespace claim corrected

  • What changed: the read-only SAP review returned "send back, narrowly" for the Fiori app and "accept with minors, conditional on one reversal" for the worker. I accepted every finding and dispatched two correction briefs in parallel. I also correct my own claim from earlier today: the OData V4 namespace and the first URL segment derive from the service binding (group) name, not the service definition — the tenant serves /api_currencyexchangerate/srvd_a2x/sap/currencyexchangerate/0001 with namespace com.sap.gateway.srvd_a2x.api_currencyexchangerate.v0001, and SAP Help shows /api_product/srvd_a2x/sap/product/0002 [source: sap-docs sap-help loio 5f45f125dfe84c20beb18f5de1512f5a; tenant EDMX line 55 and exchange-rates-cap/package.json:33,39, verified 2026-09-14]. Strongly indicated for custom UI bindings, not yet proven; V-2 confirms it.
  • Why: naming and state-machine decisions are cheap now and expensive once the RAP BO exists; the worker's drop-on-full-buffer trade-off violated ARN-003's intent by losing a poll window with no recovery path today.
  • Affected: app/, worker/, docs/api/worker.openapi.json (→ 0.2.1), PRD ARN-001/ARN-002 wording, interface-contract rows, RAP-track requirements, KNOWLEDGE landmine text.
  • Decision: (1) provisional identity is binding ZUI_ARENA_CHANGE_APPROVAL_O4, definition ZUI_ARENA_CHANGE_APPROVAL, URL first segment and namespace from the binding. (2) The approval state machine gains post-execution states: PENDING → APPROVED → EXECUTING → SYNCED | FAILED, REJECTED terminal, FAILED → retrySync → EXECUTING; the worker drives EXECUTING/SYNCED/FAILED through actions on the A2X binding so an approved record can never be executed twice (ARN-006). (3) Approve/Reject leave the list toolbar and live only on the object page, where the staged payload is shown in its own facet before the decision (ARN-010 is not decorative). (4) The object-type token is DOCUMENTS everywhere (PRD ARN-001 is the requirement source); the worker contract follows. (5) A full ingest buffer at poll time is a tick failure: the cursor holds and health degrades; duplicates on recovery are accepted because SAP is the ledger. (6) Every status code the worker emits is governed by a default problem+json response plus explicit 415/413. (7) Error text in /health and run snapshots is a fixed phrase, never a raw upstream message. (8) ApprovedBy becomes DecidedBy; the semantic key is ItemNumber + ChangeType + ArenaEcoId; the staged payload is abap.string on the RAP side.

2026-09-14 — Worker contract conformance is now a test, not a review step

  • What changed: I added worker/test/contract.test.ts (35 tests): every components.schemas.* in docs/api/worker.openapi.json compiles under the JSON Schema 2020-12 dialect, every documented status code of every operation is exercised through the real Fastify instance and its body validated against the contracted schema, all error bodies are application/problem+json, and 5xx bodies carry no upstream or internal detail. A reverse check fails the suite if a status code is added to the contract without a test. 118 tests green. Dev dependencies added: ajv 8.20, ajv-formats 3.0 (test only; Ajv was already transitive via Fastify).
  • Why: ARN-009 says the implementation conforms to the contract; today's review found /health drifting off its enum. A schema-driven suite turns that class of finding into a red test.
  • Affected: worker/test/, worker/package.json, ARN-009.
  • Decision: the reserved 502 response stays unattached to any operation and is covered only through the error-handler path until a route calls Arena synchronously.

2026-09-14 — Fiori app rebound to the SAP gateway service shape; UX polished

  • What changed: I rewrote the mock service and every annotation target to the shape an ABAP Cloud OData V4 UI service emits (com.sap.gateway.srvd. zui_arena_change_approval.v0001, alias SAP__self, ChangeApproval_Type, entity set ChangeApproval), re-pointed the manifest to the UI-binding URL, renamed the app id to com.minicircuits.arenaplm (the folder stays the structural app/), seeded six mock rows across all four states, pinned the mock server to port 8082, and polished the UI: semantic key on the item number, default sort (status, then newest request) with a PENDING default filter loaded on start, importance tiers for responsive columns, hidden technical fields, a second header facet with the Arena ECO and SAP change number, an approvals icon, multi-line staged payload, and status-dependent action availability via Core.OperationAvailable on IsApprovable / IsRetriable. Typecheck, lint, build and the UI5 linter are clean; the mock service answers $metadata, the entity set (6 rows, 3 pending) and the annotation file with 200.
  • Why: the review's ship-blocker — annotations against an invented namespace silently render nothing on the real service [source: KNOWLEDGE.md 2026-09-14 landmine]. Polish makes the approver's landing page the pending queue, which is the job the app exists for (ARN-002, ARN-010).
  • Affected: app/ (metadata, mock data, annotations, manifest, i18n, Component, ui5*.yaml, package.json, OPA journeys, README), PRD RAP-track requirements (harvested below), V-2.
  • Decision: the Fiori generator's modify catalog covers no annotation or manifest-setting change, so these edits are hand-authored against cited Fiori Elements documentation; the manifest _version moved to 2.11.0 to match minUI5Version 1.152 [source: sap-docs /sapui5/03_Get-Started/step-10, verified 2026-09-14]. The ui5-mcp-server cannot see this filesystem (ENOENT on realpath), so UI5 linting ran through @ui5/linter directly.

2026-09-14 — Worker review fixes landed; contract v0.2.0

  • What changed: contract first, then code: /health session state enum is none|active|expired|refreshing, status turns degraded on the last poll or login failure and a poller block reports last run/success/error; SyncRunRequest is strictly additionalProperties:false with no type coercion and no defaults; the webhook intake answers 503 + Retry-After when the bounded buffer (WEBHOOK_QUEUE_MAX_SIZE, default 10000) is full; a reserved 502 response maps upstream Arena errors without leaking bodies. In code: the session TTL now flows from config by construction (a rename is a compile error), the poll cursor advances only after a successful fetch, shutdown drains in-flight runs and the current poll tick under SHUTDOWN_TIMEOUT_MS through one Fastify onClose path, HTTP calls carry ARENA_HTTP_TIMEOUT_MS, integer env parsing is strict, duplicate SYNC_OBJECT_ORDER entries are rejected, and npm run dev loads .env when present. 83 tests green (from 37); build and lint clean.
  • Why: six verified correctness findings, all latent until the real Arena client lands — cheapest to fix before it does.
  • Affected: worker/, docs/api/worker.openapi.json (0.1.0 → 0.2.0), ARN-005, ARN-009.
  • Decision: a full buffer during a poll drops the overflow and still advances the cursor (retrying the window would duplicate the events that fit); those changes are recovered by the V-3 durable cursor, not by the worker. I am having this trade-off reviewed. The worker package version stays 0.1.0 until a release; /health.version reports it.

2026-09-14 — ADR-003 gate hardened; secret-bearing files git-ignored

  • What changed: I closed the four governance findings from the review. The consult gate now covers Bash/MultiEdit/NotebookEdit/filesystem-MCP writes, only grounding-server and web consultations refresh the marker, hooks resolve the repo from CLAUDE_PROJECT_DIR, the gate fails closed without jq, worker/ is no longer SAP-gated, and a 37-case pipe-test harness guards the scripts. .gitignore now excludes .mcp.json (live tokens), .claude/settings.local.json, **/.vscode/, **/.remember/, app/.appGenInfo.json; a dry-run git add -A stages none of them.
  • Why: enforcement that the standard tools bypass is prose, not structure (ADR-003's premise); and the repo's first commit must not publish tokens.
  • Affected: .gitignore, .claude/settings.json, .claude/hooks/* (+ tests/run.sh), docs/adr/ADR-003 (amended).
  • Decision: fail closed on a missing classifier dependency, accepting that a host without jq cannot edit anything in this repo until it is installed.

2026-09-14 — Code review accepted; correction to the scaffold entry; hardening wave dispatched

  • What changed: I ran a full code review over the package (31 candidate findings, all verified, none refuted) and accepted its top ten as the next build wave. I also correct my 2026-09-14 scaffold entry below: the generator emitted app id com.minicircuits.app (not com.minicircuits.arenaplm), no mock rows were seeded (the mockdata path did not exist), and the mock server was not pinned to port 8082. Those three claims described intent, not the repo; this wave makes them true.
  • Why: two findings are ship-blockers. (1) .mcp.json carries live bearer tokens and is not git-ignored in a repo with zero commits. (2) Every annotation target in the Fiori app uses the invented namespace com.minicircuits.arenaapproval; an ABAP Cloud OData V4 service emits com.sap.gateway.<srvd|srvd_a2x>.<service>.v0001 with alias SAP__self and <Entity>_Type entity types, so against the real service the List Report would render with no columns, filters, facets or actions — and the mock hid it because mock metadata and annotations agreed with each other [source: live tenant my429480 EDMX, API_CURRENCYEXCHANGERATE.edmx lines 55/57/95, verified 2026-09-14]. The remaining findings are worker correctness bugs (session TTL silently discarded, poll cursor advanced before fetch, /health off-contract, non-strict Ajv, unbounded queue, SIGTERM killing runs) and the ADR-003 gate being bypassable (Bash/MultiEdit writes unmatched; any MCP call refreshing the marker; absolute hook paths).
  • Affected: .gitignore, .claude/ (hooks, settings), worker/, docs/api/worker.openapi.json (→ v0.2.0), app/ (metadata, manifest, annotations, mock data, app id), PRD interface contracts, V-2, status.
  • Decision: I split the approval-BO service into two bindings — an OData V4 UI binding for the Fiori app and an OData V4 Web API (A2X) binding for the worker's technical user — because SAP's own path builds the Fiori UI on a UI service binding [source: sap-docs sap-help loio 5717c0a1dafc4335add0207b81c39cef, verified 2026-09-14]. The app now targets the provisional identity zui_arena_change_approval (namespace com.sap.gateway.srvd.zui_arena_change_approval.v0001); the exact namespace, entity-type suffix and URL segment are reconciled against the live $metadata at V-2 before any deploy. Worker contract v0.2.0: session state enum gains expired/refreshing, status becomes degraded on poll or login failure, SyncRunRequest is strictly additionalProperties:false, and the webhook intake returns 503 when the bounded buffer is full. Gate hardening: only the grounding servers refresh the consult marker; Bash, MultiEdit, NotebookEdit and filesystem-MCP writes are gated; hooks resolve the repo from CLAUDE_PROJECT_DIR; the gate fails closed without jq; the non-SAP worker/ path leaves the SAP gate. I dispatched the three independent streams (config hardening, worker fixes, Fiori correction + polish) in one parallel wave; tests and the read-only SAP review are gated behind them.

2026-09-14 — Fiori Elements UI scaffolded (com.minicircuits.arenaplm), on mock, at the package root

  • What changed: I scaffolded the approval workbench's Fiori Elements List Report / Object Page UI as com.minicircuits.arenaplm (TypeScript, UI5 1.152) in the structural app/ subfolder (sibling to worker/; the folder name is structural, not the app identity) — generated via the Fiori tools MCP generate_fiori_app_odata. It runs on a MOCK OData V4 service: entity ChangeApproval whose fields I grounded in the predecessor's real approvals contract (docs/predecessor-flow.md), with Status carrying a distinct FAILED state per ARN-002; audit fields (RequestedBy/ApprovedBy/DecidedOn) and StatusCriticality are inferred and flagged for reconciliation. Curated UI.LineItem/HeaderInfo/SelectionFields/FieldGroup+Facets; 4 seeded mock rows. Dev/mock server pinned to port 8082 (8080 is a local app on the dev host). The Fiori generator recognizes the app at the root (list_functionality returns the modify catalog).
  • Why: to stand up the launchpad UI layer (ARN-007) now and make it iterable with the Fiori generator without waiting on the gated on-stack RAP service — the proven label-poc mock-first pattern. The live predecessor (arena-plm on CF, verified up: /api/health 200, v0.0.1) is the base of record for the domain/field shape.
  • Affected: app/ (new app files: webapp/, ui5*.yaml, package.json, tsconfig.json); worker/ untouched; root .gitignore covers app/. No PRD requirement completed — this is interim mock UI.
  • Decision: the mock OData service (com.minicircuits.arenaapproval / zarena_change_approval) is a stand-in; the real binding is the RAP approval-BO service (V-2), and the mock entity is the reconciliation target once that service exists. App id follows the estate com.minicircuits.* convention; the app lives in the structural app/ subfolder (sibling to worker/) — the folder name is structural, not the app identity.

2026-09-10 — Build wave 1 closed: worker scaffold accepted against the contract

  • What changed: I accepted the connectivity-worker scaffold in worker/ after two correction rounds at the contract seam: scope made required and the request's objects selector honored; all 400/401/404 bodies moved to RFC 9457 application/problem+json; the wire SyncRun aligned to the amended contract (execution-ordered objects progress array, no objectOrder); and unknown request properties strictly rejected (Ajv removeAdditional: false) rather than silently stripped. Final state verified by my own run: build, lint, and 37 tests green. Stack: Fastify 5.12, TS ~5.9 (pinned — see the KNOWLEDGE.md toolchain entries), Vitest 4, Node 24.
  • Why: API-first (ARN-009) is only real if the implementation is held to the contract at review — and silent stripping of unknown properties is the same quiet-divergence failure class the rest of this package's enforcement exists to prevent.
  • Affected: worker/ (accepted), docs/api/worker.openapi.json (final v0.1.0), PRD status.
  • Decision: next worker wave is the live Arena client POC (session, delta via the outbound-integration queue per the V-3 findings); the S/4HANA executor leg stays stubbed until V-2 defines the approval-BO service binding.

2026-09-10 — Predecessor flow extracted; new tombstones harvested; ARN-010 adopted

  • What changed: I extracted the predecessor's real end-to-end mechanism into docs/predecessor-flow.md (with file:line cites): it is an operator-driven staging workbench — the webhook never syncs (a literal TODO), there is no scheduler, BOM/document writes are non-idempotent, REJECTED conflates human rejection with SAP failure, and the approved preview is discarded at execution time. I harvested the durable behavioral findings into KNOWLEDGE.md (BOM EngineeringChangeDocForEdit / HeaderChangeDocument, IsActiveForChangeNumber silent-discard, ProductDescription full-key PATCH, ProcurementType+MRPType coupling, Arena WORKING-revision overlay, /items/{guid}/changes 404, no server-side date filter on /changes, outbound-integration queue as the clean cursor, plus three landmines). I adopted ARN-010 (the approved payload is the executed payload) and sharpened ARN-002 (execution failure is a distinct state), ARN-006 (existence checks), and V-3 (cursor mechanism findings).
  • Why: the rebuild must be designed from verified behavior, not assumption — and the extraction proved the approval workflow's authority was decorative in the predecessor, which is exactly the class of defect the RAP BO design must preclude structurally.
  • Affected: docs/predecessor-flow.md (new), KNOWLEDGE.md, PRD.md (ARN-002, ARN-006, ARN-010, V-3), CLAUDE.md (files map).
  • Decision: executor, poller, and approval-domain design work cites docs/predecessor-flow.md sections, not memories of the old code.

2026-09-10 — Worker API contract v0.1.0 accepted; sap-api CLI adopted; V-1 partially verified

  • What changed: I accepted docs/api/worker.openapi.json v0.1.0 after running an SAP API style review against the bundled style-guide references and applying two corrections (SAP lifecycle metadata x-sap-shortText + x-sap-stateInfo: beta; a documented 400 on POST /admin/sync-runs). I adopted the sap-api CLI on this box for live tenant/Arena reads, EDMX fetch, and OpenAPI generation (recorded in CLAUDE.md). Using it, I partially verified V-1: my business user AZAW holds 172 roles but no developer-extensibility role, and no such role exists in the tenant catalog to assign — one must first be created from the SAP_BR_DEVELOPER template [source: sap-docs /fiori-tools-samples/misc/s4hana/README + sap-help loio e3527dfa1c5a41f69d4e63691f174f0a, verified 2026-09-10].
  • Why: API-first (ARN-009) needs a governed, style-conformant contract before the worker's surface hardens, and V-1 is the gate for the entire on-stack track — every fact I can verify from this box now shortens the remaining manual check.
  • Affected: docs/api/worker.openapi.json, CLAUDE.md, PRD.md (V-1, status).
  • Decision: read commands of sap-api are part of my design/acceptance toolkit; mutating commands are delegated like any other write.

2026-09-10 — API-first adopted (ARN-009); build wave 1 dispatched

  • What changed: I adopted the API-first rule — every interface this package owns gets an OpenAPI 3.1 JSON contract under docs/api/ before or with the change (CLAUDE.md rule 7, PRD ARN-009). I designed the worker's inbound surface (Arena webhook intake, health, sync-run admin; bearer placeholder pending OQ-6) and dispatched build wave 1 as two parallel items: the contract formalization and the TypeScript worker scaffold under worker/ (Arena session core per KNOWLEDGE.md, HTTP surface, delta-poller skeleton, sync-executor stub — no SAP write code).
  • Why: contracts must govern implementation from the first line of code, and the worker track is the only unblocked track while V-1 is unverified.
  • Affected: CLAUDE.md (rule 7), PRD.md (ARN-009, interface contracts, status), docs/api/ (new), worker/ (new, in progress).
  • Decision: the on-stack RAP/Fiori track stays gated on V-1; nothing SAP-write-shaped lands in the worker until the approval BO contract exists (V-2).

2026-09-10 — CLAUDE.md brought up to date with the repo it maps

  • What changed: I extended CLAUDE.md with what a fresh session needs but could not previously see from it: the five-specialist delegation table (with pointer to docs/agent-roster.md), an explicit dated repo-state note (governance-only, no build/lint/test commands exist yet), the consult-gate exemptions and remedy appended to rule 6, and Files-table rows for docs/agent-roster.md and .claude/hooks/.
  • Why: CLAUDE.md is the map, and it lagged the 2026-09-04 agent-roster and enforcement-kit additions; a fresh session would also hunt for build tooling that does not exist yet.
  • Affected: CLAUDE.md, CHANGELOG.md. Rule numbering unchanged, so the rule-6 references in ADR-003 and the hooks stay valid.
  • Decision: when the first implementation code lands, its commands are recorded in CLAUDE.md in the same turn — the repo-state section says so.

2026-09-04 — Removed foreign sap-odata scaffold bundle; landmine recorded

  • What changed: I removed a bundle that appeared in this repo at 14:40 without my involvement — .github/agents/ + .github/skills/ (the retired, fabricating sap-odata agent trio in GitHub-Copilot layout), a root AGENTS.md routing to those agents, and .vscode/mcp.json pointing at a Windows-only MCP binary that cannot run on this host. I recorded a KNOWLEDGE.md landmine describing the bundle and its likely source (the harieprasad.sap-odata-mcp VS Code extension scaffolding on folder open).
  • Why: the root AGENTS.md would have been read as project instructions, routing sessions to agents whose backing tools do not exist — the exact fabrication failure this package's enforcement layer was built to prevent, reintroduced silently on day one.
  • Affected: .github/ (deleted), AGENTS.md (deleted), .vscode/mcp.json (deleted), KNOWLEDGE.md (landmine added). Nothing was committed before or after; the repo's tracked-content plan is unchanged.
  • Decision: the falsification test stands — if the bundle reappears on the next VS Code open, the extension is confirmed as the writer and gets uninstalled.

2026-09-04 — Specialist agent roster designed from verified research

  • What changed: I ran a capped 4-agent research workflow (3 low-cost researchers over GitHub / SAP Community / web, 1 adversarial verifier that re-fetched every source: 37 findings → 22 confirmed, 14 downgraded or refuted and discarded) and compiled the founding kit's dedicated-agent layer: five specialists (rap-developer, fiori-developer, worker-developer, sap-code-reviewer read-only, test-engineer on the low-cost model) with tool restrictions as the role contract. Design and citations in docs/agent-roster.md; file creation delegated to .claude/agents/.
  • Why: the last founding-kit gap was specialized, grounded agents; every adopted pattern (restriction-as-enforcement, per-artifact MCP routing, model-per-role, false-positive filtering) traces to a verified source, and refuted sources are recorded so they are never re-researched.
  • Affected: docs/agent-roster.md (new), .claude/agents/ (5 files, delegated), PRD status.
  • Decision: ADT MCP server adoption is recommended but gated on V-1 — evaluate SAP's official ABAP MCP path first, ARC-1 / yzonur/sap-adt-mcp as fallbacks; nothing installed until dev-tenant access is confirmed.

2026-09-04 — ADR-003 corrected: tool preloading already exists and is active

  • What changed: I amended ADR-003's tool-loading section. Reading the 2026-09-03 performance-lag session transcript showed ENABLE_TOOL_SEARCH=false is the preload lever (binary-verified there), that it only works before bootstrap (settings.json env is too late), and that it is already active machine-wide via the claude() wrapper in ~/.bashrc — so sessions in this repo start with all tools loaded. My earlier "no setting exists" claim was wrong in practice; the SessionStart load-first order stays as fallback for launch paths that bypass the wrapper.
  • Why: the requirement "tools loaded automatically on session start" is satisfied by existing machine config, and the record must say so accurately.
  • Affected: docs/adr/ADR-003 (amended in place, correction dated).
  • Decision: rely on the wrapper for preloading; keep the hook fallback.

2026-09-04 — Ground-truth enforcement kit installed (ADR-003)

  • What changed: I added project hooks that make MCP-first grounding structural: a SessionStart grounding charter, a per-prompt SAP-REFLEX injection, a consultation gate that denies edits to SAP artifacts unless an mcp__*/WebSearch/WebFetch consultation happened within 30 minutes, and a citation duty (CLAUDE.md rule 6) with a reminder hook on governance-doc edits. This kit becomes part of the founding kit for every future package.
  • Why: the old estate proved advisory routing fails — the MCP servers and skills were never consulted regardless of stack. Enforcement had to move from prose to hooks. I verified against the Claude Code settings schema that no preload setting exists for deferred tools; the slim loadout plus the SessionStart load-first order is the working equivalent.
  • Affected: .claude/settings.json, .claude/hooks/ (3 scripts), .gitignore, CLAUDE.md (rule 6), docs/adr/ADR-003 (new).
  • Decision: consultation is a precondition enforced by a deny gate, not a guideline; uncited SAP claims are hypotheses.

2026-09-04 — Redesigned on-stack: RAP + Fiori in the tenant (ADR-002)

  • What changed: I moved the target architecture into the S/4HANA tenant — approval domain as a custom RAP business object, Fiori Elements app in the tenant launchpad, IAM app/business catalog/business roles as the only access control, custom CDS views for discoverability. Side-by-side shrinks to one connectivity worker for Arena (webhook, polling, session, files, and initially the sync executor). CAP exits the architecture; the MCP loadout moved to sap-docs / abap-docs / sap-released-objects / fiori / ui5. PRD rewritten (ARN-007/008 added, OQ-1..4 resolved, V-1..V-3 verification gates added); ADR-001 amended.
  • Why: the decisive test came from the business side — the showcased apps were invisible from inside S/4HANA (not in the launchpad, not in Custom CDS Views), reachable only through standalone URLs with weak control. A side-by-side CAP app would fail the same test. I verified the on-stack path (developer extensibility: RAP + Fiori deploy + IAM; key-user tier as fallback) against SAP documentation via the MCP servers before deciding.
  • Affected: PRD.md, CLAUDE.md, docs/adr/ADR-001 (amended), docs/adr/ADR-002 (new), .mcp.json (loadout).
  • Decision: on-stack first — the tenant hosts the application; BTP hosts only what the tenant cannot run. The launchpad is the only front door.

2026-09-04 — Package founded; knowledge bankruptcy declared

  • What changed: I created this standalone package home under ~/projects/sap-integrations-mcl/, decoupled from the old multi-package estate. I carried over only dated tombstones and landmines (KNOWLEDGE.md) and the proven interface contracts (PRD.md); all other predecessor knowledge is deliberately left behind, to be re-derived from code and live systems as needed.
  • Why: the single-estate setup had grown past what one working context can maintain, and its accumulated undated knowledge had begun to rot. The Express implementation also sat outside SAP's toolchain, so none of the SAP guidance tooling ever engaged — a signal that the stack, not the tooling, was wrong.
  • Affected: this package only. The predecessor at ~/projects/sap-apps/arena-plm is now reference-only.
  • Decision: I chose a CAP-first rebuild over transplanting the Express app (ADR-001), with a deliberately slim tool loadout (three MCP servers, seven skills) matched to that stack.