Skip to content

fix: Built-in Tools row style — single line, 40px#5

Merged
ericodom merged 1 commit into
mainfrom
worktree-builtin-tools-deploy
Apr 12, 2026
Merged

fix: Built-in Tools row style — single line, 40px#5
ericodom merged 1 commit into
mainfrom
worktree-builtin-tools-deploy

Conversation

@ericodom
Copy link
Copy Markdown
Contributor

Drop the description sub-line from the Tool cell and switch row height from h-14 to h-10 so the table matches MCP Servers.

… h-10

Drop the description sub-line from the Tool cell and switch row height
from h-14 to h-10 (40px) so the table reads like MCP Servers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ericodom ericodom merged commit 0405da2 into main Apr 12, 2026
3 checks passed
ericodom added a commit that referenced this pull request Apr 20, 2026
Evals was the last section still rendering the SVG placeholder. Pull
the dedicated showcase from the homepage until a real /evaluations/$runId
capture lands. Evals still appears as pillar #5 in FiveControls and as
a proof point in ProofStrip — the narrative claim is preserved; only
the fake-screenshot section goes away.

While here:
- Strip the `pending` fallback + SVG variants from ScreenshotFrame.
  Every active screenshot on the page is now a real PNG; the component
  is a pure window-chrome wrapper.
- Remove the pending/variant props from CapabilityShowcase and callers.
- Realign the two phones in MobileApp: drop the decorative
  translate-y offsets, switch from flex items-end to grid items-start
  so both phones anchor to the same top and their labels sit on the
  same baseline.

CAPTURE.md documents how to re-add the Evals section once a real
screenshot is captured.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ericodom added a commit that referenced this pull request Apr 20, 2026
* feat(www): reposition public site around governed AI adoption

Reframe apps/www from "AI infrastructure in your AWS" (architecture-first)
to "the control plane for governed AI adoption" (CTO-first). The same
five controls were already shipped in admin — they just weren't marketed.

New narrative arc:
- Hero + ProofStrip lead with governance, not self-hosting.
- AdoptionProblem frames the ban-or-adopt false choice.
- FiveControls enumerates the five governance pillars (replaces
  WhyThinkWork's three generic pillars).
- AgentTemplates / CostControl / Evals showcase each control with a
  caption-matched screenshot frame (styled SVG mockups now; real admin
  captures follow via apps/www/public/images/admin/CAPTURE.md).
- SystemModel, MemoryWedge, FinalCTA reframed to match the new voice;
  MemoryWedge moves after the control story as a durable benefit.
- All copy moves to a single apps/www/src/lib/copy.ts source so future
  edits don't drift across sections.

Meta + OG description updated. No new dependencies. No CTA changes
(docs/GitHub/login only). No new routes. No compliance badges (unearned).
Header nav anchors relock to the new section IDs.

Also includes the plan this implements:
docs/plans/2026-04-20-001-feat-www-governance-positioning-refresh-plan.md

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

* feat(www): unify design system + ship real admin/mobile captures

One-hand design pass across the whole homepage. The legacy sections
(Hero, ProofStrip, SystemModel, MemoryWedge, MobileApp, QuickStart,
FinalCTA) and the new enterprise-positioning sections (AdoptionProblem,
FiveControls, AgentTemplates, CostControl, Evals) now share one visual
vocabulary.

Shared primitives:
- SectionShell — one section wrapper with default/raised/sunken tone
  and none/top/center/cascade glow presets
- SectionHeader — one eyebrow + H2 + lede lockup with optional step marker
- CapabilityShowcase — single partial used by AgentTemplates, CostControl,
  Evals so the three showcases can never drift
- ScreenshotFrame — window-chromed frame (3 dots + route label) used for
  every product shot on the page, with styled SVG fallback while
  `pending={true}`

Adjustments:
- Hero: tighten pill eyebrow, text-balance + text-pretty on headline and lede
- ProofStrip: cardless, dot-led list with top brand hairline (no more divider grid)
- AdoptionProblem: numbered cards match FiveControls rhythm
- FiveControls: card hover states, numeric "01" marker in top-right
- SystemModel: keep the "Control wraps the system" frame, restyle to match
- MemoryWedge: replace gradient cards with unified card vocabulary
- MobileApp: single padded stage for both phones, swap Tasks → Wiki
- QuickStart: terminal chrome aligned with ScreenshotFrame chrome
- FinalCTA: echo the hero pill eyebrow to close the loop

Real product screenshots added — 9 captures committed under
apps/www/public/images/ with CAPTURE.md inventory:
- admin: dashboard, agent-templates (capabilities list), cost-analytics,
  memories-graph (all-agents view), plus memories-graph-filtered
  and thread-detail held as reserve assets
- mobile: threads-list, wiki-graph (now paired with threads in MobileApp),
  wiki-list held as reserve asset

Evals still renders its SVG mock (no capture yet) — flip `pending={false}`
in Evals.astro when a real evals-run.png lands.

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

* fix(www): drop Evals placeholder section + realign mobile phones

Evals was the last section still rendering the SVG placeholder. Pull
the dedicated showcase from the homepage until a real /evaluations/$runId
capture lands. Evals still appears as pillar #5 in FiveControls and as
a proof point in ProofStrip — the narrative claim is preserved; only
the fake-screenshot section goes away.

While here:
- Strip the `pending` fallback + SVG variants from ScreenshotFrame.
  Every active screenshot on the page is now a real PNG; the component
  is a pure window-chrome wrapper.
- Remove the pending/variant props from CapabilityShowcase and callers.
- Realign the two phones in MobileApp: drop the decorative
  translate-y offsets, switch from flex items-end to grid items-start
  so both phones anchor to the same top and their labels sit on the
  same baseline.

CAPTURE.md documents how to re-add the Evals section once a real
screenshot is captured.

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

* feat(www): elevate capability showcases from bullets to feature grid

Drop the floating bullet list next to the screenshot. Each showcase now:
- Centers the eyebrow + headline + lede above the fold of the section
- Puts the product screenshot front and center at full section width
- Promotes each proof point to a numbered feature card in a 4-up grid
  below the screenshot — each card has a pill-style mono number, a
  strong title, and a supporting sentence

Copy migrated from flat `bullets: string[]` to `features: { title, desc }[]`
in lib/copy.ts for AgentTemplates and CostControl so the grid has real
titles to render.

Dropped the `figureFirst` prop — the new layout is top-to-bottom by
construction, so left/right ordering is irrelevant.

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

* feat(www): add Audit showcase between Templates and Cost

Work the thread-detail screenshot into the page as a dedicated Audit
section. The narrative arc through the governance block now reads:
  Templates  -> control what agents CAN do
  Audit      -> record what they DID
  Cost       -> measure what it COST

Audit uses the same elevated CapabilityShowcase pattern (centered
header -> full-width screenshot -> 4-up numbered feature grid).
Features: Step-by-step execution, Token + cost per turn, Status +
attribution, Ready for evals (bridges back to the evals pillar
without needing a dedicated evals screenshot).

Flipped CostControl tone back to default so the three showcases
alternate cleanly (default -> raised -> default).

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

* fix(www): act on reviewer feedback — must-fix copy + OG + dead code

Adversarial + CTO reviewers flagged overclaims, voice-guardrail
violations, and dead code. This commit addresses the must-fix list:

Overclaim corrections (schema vs copy):
- "Tool allow-lists" -> "Tool block-lists" (copy.ts). The schema is
  blocked_tools (deny-list); the previous framing promised a permit-
  by-default model the runtime doesn't enforce. Security sign-off can
  no longer rest on a false premise.
- "Automated gates on every template change" -> "Evaluation harness
  for every template" (proofStrip + controls items + evals lede).
  Nothing in packages/api gates a template write on eval results;
  "gate" was load-bearing language without an enforcing code path.
- "Pipe the raw cost event stream into your own FinOps system" ->
  "Cost events live in the Postgres you deployed" (costControl
  features[3]). No export surface ships; the FinOps-system framing
  implied a customer contract that doesn't exist.
- "Ready for a compliance review" -> "Inspectable per thread, per
  agent, per tenant" (audit lede). Violated the file's own "no
  unearned compliance" guardrail.

Voice-guardrail compliance (top-of-file rules finally enforced):
- FiveControls headline "The guardrails your adoption review already
  requires" -> "Governance primitives, not bolted-on guardrails"
- FiveControls lede "Every control a skeptical CTO expects" ->
  "Five first-class controls a governed rollout actually requires"
- CostControl headline "No surprise invoices from a runaway agent" ->
  "Cost attributed where it happens"
- CostControl features[2] "turns into a receivable" -> "compounds into a bill"
- SystemModel lede "explain to a board" -> "hold in your head"
  (restores the original, sharper phrasing)
- AdoptionProblem bullet "Not a pilot that can't scale" -> "One system
  at every scale. The runtime a developer spins up in five commands
  is the runtime production runs on." (drop "harness" jargon too)
- MobileApp "No pull-to-refresh dance" -> removed
- FinalCTA "The harness stays yours" -> "The runtime stays yours"
  (harness is insider jargon, never defined on the page)

Hero lede split:
- One 29-word comma pile -> two sentences. Easier for a hurried scan.

Evals as a sub-feature, not a placeholder section:
- Strengthened Audit features[3] ("Evals run on the same trace") to
  carry the AgentCore + custom-assertion story in one card. The
  evals export in copy.ts is kept for when a real /evaluations/$runId
  capture arrives and the dedicated showcase can be re-added
  (instructions in CAPTURE.md).

Dead code + orphan asset cleanup:
- Moved unused reserve captures out of public/ into apps/www/assets/
  so they stay versioned but stop shipping: memories-graph-filtered.png,
  mobile/wiki-list.png, mobile/tasks-list.png.
- Updated CAPTURE.md: removed references to the long-deleted `pending`
  prop and SVG fallbacks; documented how to re-add the Evals showcase.

OG image:
- Replaced the stale og-image.png (pre-positioning) with a fresh
  1200x630 export matching the new hero. Rendered via Chrome headless
  from scripts/og-source.html (kept in-tree so the asset is
  regeneratable).

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

* fix(www): reorder showcases so Audit leads, Templates lands last

The Templates screenshot is the Capabilities/Skills list, which is
the weakest visual of the four product shots. Leading with it killed
momentum right after the five-controls overview.

New showcase order: Audit -> Cost -> Templates -> SystemModel.

Narrative reads: "See what your agents actually did (Audit) ->
See and cap what they spent (Cost) -> Define the boundary for what
they can do (Templates) -> One admin surface for all of it (System)."

Rebalanced section tones so they still alternate cleanly:
FiveControls raised -> Audit default -> Cost raised -> Templates
default -> System raised.

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

* fix(www): sharpen the FinalCTA close

Cut the "Keep the runtime. Keep the memory. Keep the work record."
triplet — it repeats without adding meaning. Replace with a tighter
two-sentence close that commits to the concrete security posture.

Headline changes from the abstract "The runtime stays yours." to the
action pair "Adopt AI. Keep control." — which directly answers the
"ban vs adopt" framing the AdoptionProblem section opened with.

Eyebrow moves from "Deploy on your terms" to "Your AWS · Your rules"
(pulled into copy.ts so FinalCTA.astro reads from one source).

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ericodom added a commit that referenced this pull request Apr 24, 2026
…hon skill (#486)

Parity pass with packages/skill-catalog/thinkwork-admin/scripts/operations/*.py.
The @thinkwork/admin-ops package now exposes every op the Python skill
ships, and the admin-ops MCP server registers all of them as MCP tools.
Sets up deprecation of the skill: agents using mcp.thinkwork.ai can
do everything the skill's Python wrappers did.

Client
- AdminOpsClient gains a `graphql(query, variables?)` helper that POSTs
  to /graphql with the same Bearer, throws AdminOpsError on error
  responses. Mutations + most reads use GraphQL (matches the Python
  skill's wire); tenants module continues to use REST since those
  handlers already exist.

Ported modules (28 ops):
- teams.ts         5 mutations + 2 reads (createTeam, add/remove team agents + users, listTeams, getTeam)
- agents.ts        3 mutations + 3 reads (createAgent, setAgentSkills, setAgentCapabilities, listAgents, getAgent, listAllTenantAgents)
- templates.ts     5 mutations + 3 reads (createAgentTemplate, createAgentFromTemplate, syncTemplateToAgent, syncTemplateToAllAgents, acceptTemplateUpdate, listTemplates, getTemplate, listLinkedAgentsForTemplate)
- users.ts         0 mutations + 3 reads (me, getUser, listTenantMembers)
- artifacts.ts     0 mutations + 2 reads (listArtifacts, getArtifact)
- _fields.ts       shared GraphQL field-selection constants mirroring reads.py

MCP tool registration (packages/lambda/admin-ops-mcp.ts)
- 25 new tools covering every ported op. Each carries a JSON Schema
  inputSchema + a non-empty description. Tenant pinning from the
  authenticated key overrides any caller-supplied tenantId on
  downstream calls.
- The existing tools/list test asserts a curated must-have set
  rather than an exact-count equality, so future ports don't
  require test churn.

Tests
- 6 new tests in packages/admin-ops/src/teams.test.ts covering
  wire-format correctness (queries contain the right operation
  names, variables carry through, errors surface as AdminOpsError).
- Full monorepo test run: 1270+ tests passing.

Not in scope
- CLI migration of `thinkwork team/agent/template/user/artifact`
  subcommands — deferred to a follow-up PR.
- Removal of packages/skill-catalog/thinkwork-admin/ — deferred to
  PR #5 after seed (PR #4) promotes mcp.thinkwork.ai to tenants.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ericodom added a commit that referenced this pull request Apr 24, 2026
…d) (#487)

Adds the missing piece between PR #482 (per-tenant keys) and #5 (skill
deprecation): a single call that preps a tenant to consume the
admin-ops MCP. After `thinkwork mcp provision -t <slug>`, the runtime
picks up the admin-ops server for any agent that gets it assigned via
agent_mcp_servers (admin SPA / future CLI command).

Handler — packages/api/src/handlers/mcp-admin-provision.ts
- POST /api/tenants/:tenantId/mcp-admin-provision
- Three steps in one call:
  1. Mint a fresh tkm_ token via the existing mcp-admin-keys helpers
     (generateToken/hashToken from #482). Insert into
     tenant_mcp_admin_keys.
  2. Store raw token in Secrets Manager at
     `thinkwork/<stage>/mcp/<tenantId>/admin-ops`, matching the
     convention skills.ts established for tenant_api_key secrets.
  3. Upsert tenant_mcp_servers (slug="admin-ops",
     auth_type="tenant_api_key",
     auth_config={secretRef, token}). Duplicates the raw token into
     auth_config.token to match mcp-configs.ts's current reader — a
     secretRef-only migration is a separate pass.
- Idempotent: re-running revokes the previous active admin-ops key
  for this tenant and rotates the secret.
- Default URL resolves to MCP_CUSTOM_DOMAIN ?? THINKWORK_API_URL +
  /mcp/admin. `body.url` overrides.
- Bootstrap auth via validateApiSecret (matches mcp-admin-keys,
  sandbox-quota-check, other service endpoints).

Terraform — terraform/modules/app/lambda-api/handlers.tf
- New handler registered in the for_each map.
- Route: POST /api/tenants/{tenantId}/mcp-admin-provision.
- No new IAM: secretsmanager:CreateSecret/UpdateSecret/GetSecretValue
  is already granted on thinkwork/* by aws_iam_role_policy.
  lambda_secrets in main.tf.

CLI — apps/cli/src/commands/mcp.ts
- thinkwork mcp provision [-t <slug>] [--url <url>] [--all]
- --all enumerates /api/tenants and iterates; partial failures
  surface non-zero exit.
- Raw token is never printed — it goes into SM + DB and stays there.
  To get a human-usable token for debugging, use
  `thinkwork mcp key create` (which returns it once).

Tests
- 4 unit tests for URL-resolution contract in
  mcp-admin-provision.test.ts.
- Existing admin-ops-mcp + mcp-admin-keys suites stay green.
- Full monorepo: 1274+ tests passing.
- Terraform validate: Success.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ericodom added a commit that referenced this pull request May 5, 2026
fix: Built-in Tools row style — single line, 40px
ericodom added a commit that referenced this pull request May 5, 2026
…hon skill (#486)

Parity pass with packages/skill-catalog/thinkwork-admin/scripts/operations/*.py.
The @thinkwork/admin-ops package now exposes every op the Python skill
ships, and the admin-ops MCP server registers all of them as MCP tools.
Sets up deprecation of the skill: agents using mcp.thinkwork.ai can
do everything the skill's Python wrappers did.

Client
- AdminOpsClient gains a `graphql(query, variables?)` helper that POSTs
  to /graphql with the same Bearer, throws AdminOpsError on error
  responses. Mutations + most reads use GraphQL (matches the Python
  skill's wire); tenants module continues to use REST since those
  handlers already exist.

Ported modules (28 ops):
- teams.ts         5 mutations + 2 reads (createTeam, add/remove team agents + users, listTeams, getTeam)
- agents.ts        3 mutations + 3 reads (createAgent, setAgentSkills, setAgentCapabilities, listAgents, getAgent, listAllTenantAgents)
- templates.ts     5 mutations + 3 reads (createAgentTemplate, createAgentFromTemplate, syncTemplateToAgent, syncTemplateToAllAgents, acceptTemplateUpdate, listTemplates, getTemplate, listLinkedAgentsForTemplate)
- users.ts         0 mutations + 3 reads (me, getUser, listTenantMembers)
- artifacts.ts     0 mutations + 2 reads (listArtifacts, getArtifact)
- _fields.ts       shared GraphQL field-selection constants mirroring reads.py

MCP tool registration (packages/lambda/admin-ops-mcp.ts)
- 25 new tools covering every ported op. Each carries a JSON Schema
  inputSchema + a non-empty description. Tenant pinning from the
  authenticated key overrides any caller-supplied tenantId on
  downstream calls.
- The existing tools/list test asserts a curated must-have set
  rather than an exact-count equality, so future ports don't
  require test churn.

Tests
- 6 new tests in packages/admin-ops/src/teams.test.ts covering
  wire-format correctness (queries contain the right operation
  names, variables carry through, errors surface as AdminOpsError).
- Full monorepo test run: 1270+ tests passing.

Not in scope
- CLI migration of `thinkwork team/agent/template/user/artifact`
  subcommands — deferred to a follow-up PR.
- Removal of packages/skill-catalog/thinkwork-admin/ — deferred to
  PR #5 after seed (PR #4) promotes mcp.thinkwork.ai to tenants.

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

Adds the missing piece between PR #482 (per-tenant keys) and #5 (skill
deprecation): a single call that preps a tenant to consume the
admin-ops MCP. After `thinkwork mcp provision -t <slug>`, the runtime
picks up the admin-ops server for any agent that gets it assigned via
agent_mcp_servers (admin SPA / future CLI command).

Handler — packages/api/src/handlers/mcp-admin-provision.ts
- POST /api/tenants/:tenantId/mcp-admin-provision
- Three steps in one call:
  1. Mint a fresh tkm_ token via the existing mcp-admin-keys helpers
     (generateToken/hashToken from #482). Insert into
     tenant_mcp_admin_keys.
  2. Store raw token in Secrets Manager at
     `thinkwork/<stage>/mcp/<tenantId>/admin-ops`, matching the
     convention skills.ts established for tenant_api_key secrets.
  3. Upsert tenant_mcp_servers (slug="admin-ops",
     auth_type="tenant_api_key",
     auth_config={secretRef, token}). Duplicates the raw token into
     auth_config.token to match mcp-configs.ts's current reader — a
     secretRef-only migration is a separate pass.
- Idempotent: re-running revokes the previous active admin-ops key
  for this tenant and rotates the secret.
- Default URL resolves to MCP_CUSTOM_DOMAIN ?? THINKWORK_API_URL +
  /mcp/admin. `body.url` overrides.
- Bootstrap auth via validateApiSecret (matches mcp-admin-keys,
  sandbox-quota-check, other service endpoints).

Terraform — terraform/modules/app/lambda-api/handlers.tf
- New handler registered in the for_each map.
- Route: POST /api/tenants/{tenantId}/mcp-admin-provision.
- No new IAM: secretsmanager:CreateSecret/UpdateSecret/GetSecretValue
  is already granted on thinkwork/* by aws_iam_role_policy.
  lambda_secrets in main.tf.

CLI — apps/cli/src/commands/mcp.ts
- thinkwork mcp provision [-t <slug>] [--url <url>] [--all]
- --all enumerates /api/tenants and iterates; partial failures
  surface non-zero exit.
- Raw token is never printed — it goes into SM + DB and stays there.
  To get a human-usable token for debugging, use
  `thinkwork mcp key create` (which returns it once).

Tests
- 4 unit tests for URL-resolution contract in
  mcp-admin-provision.test.ts.
- Existing admin-ops-mcp + mcp-admin-keys suites stay green.
- Full monorepo: 1274+ tests passing.
- Terraform validate: Success.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ericodom added a commit that referenced this pull request May 5, 2026
* feat(www): reposition public site around governed AI adoption

Reframe apps/www from "AI infrastructure in your AWS" (architecture-first)
to "the control plane for governed AI adoption" (CTO-first). The same
five controls were already shipped in admin — they just weren't marketed.

New narrative arc:
- Hero + ProofStrip lead with governance, not self-hosting.
- AdoptionProblem frames the ban-or-adopt false choice.
- FiveControls enumerates the five governance pillars (replaces
  WhyThinkWork's three generic pillars).
- AgentTemplates / CostControl / Evals showcase each control with a
  caption-matched screenshot frame (styled SVG mockups now; real admin
  captures follow via apps/www/public/images/admin/CAPTURE.md).
- SystemModel, MemoryWedge, FinalCTA reframed to match the new voice;
  MemoryWedge moves after the control story as a durable benefit.
- All copy moves to a single apps/www/src/lib/copy.ts source so future
  edits don't drift across sections.

Meta + OG description updated. No new dependencies. No CTA changes
(docs/GitHub/login only). No new routes. No compliance badges (unearned).
Header nav anchors relock to the new section IDs.

Also includes the plan this implements:
docs/plans/2026-04-20-001-feat-www-governance-positioning-refresh-plan.md

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

* feat(www): unify design system + ship real admin/mobile captures

One-hand design pass across the whole homepage. The legacy sections
(Hero, ProofStrip, SystemModel, MemoryWedge, MobileApp, QuickStart,
FinalCTA) and the new enterprise-positioning sections (AdoptionProblem,
FiveControls, AgentTemplates, CostControl, Evals) now share one visual
vocabulary.

Shared primitives:
- SectionShell — one section wrapper with default/raised/sunken tone
  and none/top/center/cascade glow presets
- SectionHeader — one eyebrow + H2 + lede lockup with optional step marker
- CapabilityShowcase — single partial used by AgentTemplates, CostControl,
  Evals so the three showcases can never drift
- ScreenshotFrame — window-chromed frame (3 dots + route label) used for
  every product shot on the page, with styled SVG fallback while
  `pending={true}`

Adjustments:
- Hero: tighten pill eyebrow, text-balance + text-pretty on headline and lede
- ProofStrip: cardless, dot-led list with top brand hairline (no more divider grid)
- AdoptionProblem: numbered cards match FiveControls rhythm
- FiveControls: card hover states, numeric "01" marker in top-right
- SystemModel: keep the "Control wraps the system" frame, restyle to match
- MemoryWedge: replace gradient cards with unified card vocabulary
- MobileApp: single padded stage for both phones, swap Tasks → Wiki
- QuickStart: terminal chrome aligned with ScreenshotFrame chrome
- FinalCTA: echo the hero pill eyebrow to close the loop

Real product screenshots added — 9 captures committed under
apps/www/public/images/ with CAPTURE.md inventory:
- admin: dashboard, agent-templates (capabilities list), cost-analytics,
  memories-graph (all-agents view), plus memories-graph-filtered
  and thread-detail held as reserve assets
- mobile: threads-list, wiki-graph (now paired with threads in MobileApp),
  wiki-list held as reserve asset

Evals still renders its SVG mock (no capture yet) — flip `pending={false}`
in Evals.astro when a real evals-run.png lands.

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

* fix(www): drop Evals placeholder section + realign mobile phones

Evals was the last section still rendering the SVG placeholder. Pull
the dedicated showcase from the homepage until a real /evaluations/$runId
capture lands. Evals still appears as pillar #5 in FiveControls and as
a proof point in ProofStrip — the narrative claim is preserved; only
the fake-screenshot section goes away.

While here:
- Strip the `pending` fallback + SVG variants from ScreenshotFrame.
  Every active screenshot on the page is now a real PNG; the component
  is a pure window-chrome wrapper.
- Remove the pending/variant props from CapabilityShowcase and callers.
- Realign the two phones in MobileApp: drop the decorative
  translate-y offsets, switch from flex items-end to grid items-start
  so both phones anchor to the same top and their labels sit on the
  same baseline.

CAPTURE.md documents how to re-add the Evals section once a real
screenshot is captured.

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

* feat(www): elevate capability showcases from bullets to feature grid

Drop the floating bullet list next to the screenshot. Each showcase now:
- Centers the eyebrow + headline + lede above the fold of the section
- Puts the product screenshot front and center at full section width
- Promotes each proof point to a numbered feature card in a 4-up grid
  below the screenshot — each card has a pill-style mono number, a
  strong title, and a supporting sentence

Copy migrated from flat `bullets: string[]` to `features: { title, desc }[]`
in lib/copy.ts for AgentTemplates and CostControl so the grid has real
titles to render.

Dropped the `figureFirst` prop — the new layout is top-to-bottom by
construction, so left/right ordering is irrelevant.

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

* feat(www): add Audit showcase between Templates and Cost

Work the thread-detail screenshot into the page as a dedicated Audit
section. The narrative arc through the governance block now reads:
  Templates  -> control what agents CAN do
  Audit      -> record what they DID
  Cost       -> measure what it COST

Audit uses the same elevated CapabilityShowcase pattern (centered
header -> full-width screenshot -> 4-up numbered feature grid).
Features: Step-by-step execution, Token + cost per turn, Status +
attribution, Ready for evals (bridges back to the evals pillar
without needing a dedicated evals screenshot).

Flipped CostControl tone back to default so the three showcases
alternate cleanly (default -> raised -> default).

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

* fix(www): act on reviewer feedback — must-fix copy + OG + dead code

Adversarial + CTO reviewers flagged overclaims, voice-guardrail
violations, and dead code. This commit addresses the must-fix list:

Overclaim corrections (schema vs copy):
- "Tool allow-lists" -> "Tool block-lists" (copy.ts). The schema is
  blocked_tools (deny-list); the previous framing promised a permit-
  by-default model the runtime doesn't enforce. Security sign-off can
  no longer rest on a false premise.
- "Automated gates on every template change" -> "Evaluation harness
  for every template" (proofStrip + controls items + evals lede).
  Nothing in packages/api gates a template write on eval results;
  "gate" was load-bearing language without an enforcing code path.
- "Pipe the raw cost event stream into your own FinOps system" ->
  "Cost events live in the Postgres you deployed" (costControl
  features[3]). No export surface ships; the FinOps-system framing
  implied a customer contract that doesn't exist.
- "Ready for a compliance review" -> "Inspectable per thread, per
  agent, per tenant" (audit lede). Violated the file's own "no
  unearned compliance" guardrail.

Voice-guardrail compliance (top-of-file rules finally enforced):
- FiveControls headline "The guardrails your adoption review already
  requires" -> "Governance primitives, not bolted-on guardrails"
- FiveControls lede "Every control a skeptical CTO expects" ->
  "Five first-class controls a governed rollout actually requires"
- CostControl headline "No surprise invoices from a runaway agent" ->
  "Cost attributed where it happens"
- CostControl features[2] "turns into a receivable" -> "compounds into a bill"
- SystemModel lede "explain to a board" -> "hold in your head"
  (restores the original, sharper phrasing)
- AdoptionProblem bullet "Not a pilot that can't scale" -> "One system
  at every scale. The runtime a developer spins up in five commands
  is the runtime production runs on." (drop "harness" jargon too)
- MobileApp "No pull-to-refresh dance" -> removed
- FinalCTA "The harness stays yours" -> "The runtime stays yours"
  (harness is insider jargon, never defined on the page)

Hero lede split:
- One 29-word comma pile -> two sentences. Easier for a hurried scan.

Evals as a sub-feature, not a placeholder section:
- Strengthened Audit features[3] ("Evals run on the same trace") to
  carry the AgentCore + custom-assertion story in one card. The
  evals export in copy.ts is kept for when a real /evaluations/$runId
  capture arrives and the dedicated showcase can be re-added
  (instructions in CAPTURE.md).

Dead code + orphan asset cleanup:
- Moved unused reserve captures out of public/ into apps/www/assets/
  so they stay versioned but stop shipping: memories-graph-filtered.png,
  mobile/wiki-list.png, mobile/tasks-list.png.
- Updated CAPTURE.md: removed references to the long-deleted `pending`
  prop and SVG fallbacks; documented how to re-add the Evals showcase.

OG image:
- Replaced the stale og-image.png (pre-positioning) with a fresh
  1200x630 export matching the new hero. Rendered via Chrome headless
  from scripts/og-source.html (kept in-tree so the asset is
  regeneratable).

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

* fix(www): reorder showcases so Audit leads, Templates lands last

The Templates screenshot is the Capabilities/Skills list, which is
the weakest visual of the four product shots. Leading with it killed
momentum right after the five-controls overview.

New showcase order: Audit -> Cost -> Templates -> SystemModel.

Narrative reads: "See what your agents actually did (Audit) ->
See and cap what they spent (Cost) -> Define the boundary for what
they can do (Templates) -> One admin surface for all of it (System)."

Rebalanced section tones so they still alternate cleanly:
FiveControls raised -> Audit default -> Cost raised -> Templates
default -> System raised.

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

* fix(www): sharpen the FinalCTA close

Cut the "Keep the runtime. Keep the memory. Keep the work record."
triplet — it repeats without adding meaning. Replace with a tighter
two-sentence close that commits to the concrete security posture.

Headline changes from the abstract "The runtime stays yours." to the
action pair "Adopt AI. Keep control." — which directly answers the
"ban vs adopt" framing the AdoptionProblem section opened with.

Eyebrow moves from "Deploy on your terms" to "Your AWS · Your rules"
(pulled into copy.ts so FinalCTA.astro reads from one source).

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

---------

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

* feat(compliance): U5 — wire emitAuditEvent at 9 SOC2 starter-slate call sites

Phase 3 U5 of the compliance audit-event log. U1-U4 shipped the schema,
roles, write helper, and outbox drainer; this PR is the first time
production traffic causes audit rows to land.

Wire-ups:
  - agent.created / agent.deleted: createAgent + deleteAgent resolvers
    wrap their writes in db.transaction with emitAuditEvent inside
    (control-evidence tier — audit failure rolls back the mutation).
  - user.invited: createInvite REST handler emits inside the
    invite-insert transaction. apikey path emits actorType="system",
    actorId="platform-credential" (the x-principal-id header is an
    unverified self-assertion per tenant-membership.ts:112-114).
  - mcp.added / mcp.removed: mcpRegisterServer + mcpDeleteServer emit
    inside their existing CRUD transactions; mcpDeleteServer captures
    the deleted url via .returning() instead of a SELECT-before-delete.
  - workspace.governance_file_edited: workspace-files.ts handlePut
    routes governance file edits (AGENTS.md, GUARDRAILS.md,
    CAPABILITIES.md, PLATFORM.md, MEMORY_GUIDE.md, USER.md, plus
    SKILL.md markers) through a wrapping db.transaction that emits
    FIRST and runs the S3 PutObjectCommand SECOND so an S3 throw
    rolls back the audit row. Non-governance edits keep their existing
    unwrapped fast path.
  - agent.skills_changed: a separate narrow tx emits after derive
    returns changed=true. Telemetry tier — derive's writes already
    committed before the audit emit, so an emit failure does not
    roll back skill state. The underlying SKILL.md edit is itself
    audited as workspace.governance_file_edited.

Allow-list update:
  - event-schemas.ts: agent.skills_changed allow-list swapped from
    {skillIds, previousSkillIds} → {addedSkills, removedSkills}.
    The registry entry was a placeholder; this is its first caller.

Telemetry deviation:
  - The Cognito synchronous-trigger emits (auth.signin.success,
    user.created) are deferred to a follow-up PR alongside the new
    auth-audit-trigger Lambda. Per master plan U5, those emits are
    telemetry-tier (audit failure must NOT block sign-in) and ship
    with their own Terraform + IAM wiring.

Tests:
  - 5 cross-cutting integration tests in
    test/integration/compliance-event-writers/cross-cutting.integration.test.ts
    covering tier rollback, the new agent.skills_changed delta shape,
    legacy-key drop, unknown-key drop, and governance file diff
    transform truncation.
  - U3 unit tests updated to the new agent.skills_changed allow-list
    keys.
  - Existing workspace-files-handler / agents-authz /
    admin-resolvers-idempotency-wired tests updated to mock
    db.transaction + emitAuditEvent so handler tests don't need a
    working compliance.audit_outbox connection.

Plan: docs/plans/2026-05-07-005-feat-compliance-u5-event-writers-plan.md

Deferred (with rationale in plan §Scope Boundaries):
  - auth.signin.failure (no Cognito Lambda trigger for failed auth)
  - auth.signout (no logout mutation today)
  - user.disabled / user.deleted (no current admin path)
  - data.export_initiated (U11 ships the export job)
  - U5 Phase A: auth-audit-trigger Lambda + 6-file Terraform wiring
    (separate PR for focused review)

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

* fix(review): apply autofix feedback

Three safe_auto fixes from ce-code-review:

1. mcpUrlPreTransform now strips credential-shaped query params
   (api_key, token, access_token, client_secret, etc.) in addition to
   userinfo. Pre-fix, ?api_key=sk-live-abc would have persisted into
   audit_events permanently. (SEC-U5-001)

2. mcpDeleteServer now SELECTs the row tenant-scoped first and throws
   inside the wrapping tx on no-match. The prior code let the
   agentMcpServers cascade delete COMMIT inside the tx when the
   tenant ownership check failed (cross-tenant probe). Fixed by
   gating the cascade on a SELECT-then-throw pattern. (SEC-U5-003 /
   correctness #2)

3. Removed dead transactionMockImpl hoisted variable in
   workspace-files-handler.test.ts and gave emitMockImpl a default
   resolved value so the mock returns the real shape. (correctness #5)

3 redaction tests added covering credential query-param stripping for
api_key, token/access_token/client_secret, and combined userinfo +
query-param cases.

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

* fix(test): add COMPLIANCE_* exports to skills-handler test mocks

skills-complete-handler.test.ts and skills-start-handler.test.ts mock
@thinkwork/database-pg/schema with a hand-curated subset. After U5
wired emitAuditEvent into skills.ts (mcpRegisterServer /
mcpDeleteServer for the mcp.added / mcp.removed events), the schema
module now exports COMPLIANCE_EVENT_TYPES, COMPLIANCE_ACTOR_TYPES,
and auditOutbox — all of which compliance/emit.ts pulls in at
module-load time.

CI's vitest run failed on these two suites because the mock factory
omitted the new exports. The handlers under test (skills-complete,
skills-start) do not exercise the MCP CRUD paths, so the mock values
just need to be present, not functional.

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant