Commit graph

17 commits

Author SHA1 Message Date
RissRIce
1cfec322ac
fix(web): validate ontology pagination (#138)
Some checks failed
CI / build (push) Has been cancelled
test / test (push) Has been cancelled
2026-08-10 18:59:16 -07:00
4c88155f08
test(web): fail the build when marketing copy drifts from shipped providers (#126)
Some checks are pending
CI / build (push) Waiting to run
test / test (push) Waiting to run
The last three PRs all fixed the same class of bug. /credential-sharing
and README.md are hand-written copy; the providers they advertise are a
real registry in @logicsrc/plugin-credential-sharing. Nothing connected
the two, so the `team` provider shipped on 2026-07-13 and three weeks
later both surfaces still described a five-provider tool with no mention
of teams. The docs were right the whole time -- only the pages people
actually land on had gone stale, which is worse, because it reads as
"the product cannot do this" rather than as a documentation gap.

Assert it instead. For every provider in the registry, the Credential
Sharing section and the README must say something that counts as
advertising it. The registry's own `name` cannot be the proof -- `env`
is "Local .env file" and `team` is "LogicSRC Team Vault", neither of
which is how the copy reads -- so each provider declares its own
pattern, and a provider with no declaration fails too. That way adding
a provider forces a deliberate answer about the customer-facing copy.

Verified against the bug it is meant to catch: reverting the team copy
reproduces "These providers ship but /credential-sharing never mentions
them: team", and reverting the README line reproduces the same for
sh1pt and team.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 07:18:13 -07:00
f41abbd712 feat(web): put the one-line install in front of everyone
The CLI is the product, and the way you get it was nowhere on the site. You
had to already know the URL of a script served out of public/.

Two placements, one command:

- The homepage hero gets the loud version, directly under the lede and above
  the fold -- a bordered dark panel, the command at full size, Copy alongside.
- Every page carries a compact version in the rail, between the brand and the
  nav. Present on arrival, never competing with navigation.

Both come from renderInstallCommand() in one module. The homepage builds its
HTML as a string and the rest of the site is JSX, which is precisely the shape
that lets one copy of a command drift while the other stays right -- so there
is one definition and SiteShell renders it rather than restating it.

The command keeps its flags: `curl -fsSL`. Without -f, curl prints an HTTP
error body and still exits 0, so a 404 gets piped into sh; without -L the
install breaks the first time the URL redirects. This is the form install.sh
already documents in its own header.

Copy is one delegated listener on document for any [data-copy] button, mounted
site-wide in the layout. Delegation because the two placements arrive by
different rendering paths and a document listener does not care which; it also
means the next copy button needs the attribute and no wiring. It falls back to
a throwaway textarea + execCommand outside a secure context, where
navigator.clipboard is simply undefined, so the button never no-ops silently.

The contract tests pin the command, both placements, and that the clipboard
payload equals the visible text -- a Copy button that hands over something
other than what is on screen is worse than no button. They also read
public/install.sh and assert it is #!/bin/sh and documents this exact command,
so `| sh` cannot quietly become a lie.

apps/logicsrc-web: 13 new tests pass, 46 total. The ontology-api contract file
fails to resolve @logicsrc/validators, which it also does on a pristine
origin/master -- unbuilt workspace package, unrelated to this change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 12:55:30 -07:00
3649f78fb6
feat(web): serve the CLI login flow from the apex (#106)
`logicsrc login` defaults to https://logicsrc.com (#104), but every path it
needs returns 404 there: the apex runs the marketing app, while /cli/* lives in
apps/pwa on its own service.

Proxy those paths from the app that owns the apex, the same way CommandBoard is
already proxied. No DNS record, no Railway custom domain, and no subdomain --
and it makes the CLI's existing default origin correct rather than requiring
another change to chase it.

Pointing the apex at the pwa instead was the obvious alternative and is wrong:
the pwa serves `/` too, so it would take the marketing site down with it.

Proxied:
  /cli/:path*            the device-code and loopback login flows
  /api/me                identity
  /api/credshare/:path*  the credential-sharing API used after login
  /auth/:path*           /cli/authorize and /cli/device are behind requireAuth,
                         so an unauthenticated visitor is redirected here; without
                         it the browser half of the flow dead-ends on a 404

Order matters and is asserted: CommandBoard owns a catch-all /api/:path*, so
/api/me and /api/credshare/* have to match first or CLI auth silently goes to
the wrong service.

Rewrite construction is factored into pure functions so the ordering is testable
without booting Next, and degrades cleanly: with CREDENTIALS_APP_URL unset the
output is byte-identical to what shipped before.

Requires CREDENTIALS_APP_URL on the logicsrc-web service, pointing at the
credentials app's origin.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 10:25:16 -07:00
eaf0a6162b
feat(web): move Hire Us pricing to $400/hour metered billing (PRD 0002) (#102)
* feat(web): move Hire Us pricing to $400/hour metered billing (PRD 0002)

Replaces the $250/week retainer with a $400/hour rate billed against actual
hours, invoiced through CoinPay after the client approves them. A 10-hour
minimum engagement replaces the week as the unit of commitment.

The weekly price lived in 12 places, not the 3 the PRD listed: the front-page
Hire Us section, the Top-Level Pages list, /hire-us metadata, /pricing
(metadata, two FAQ answers, rate bullet), /about, llms.txt, skill.md, and the
Hire Us form success message.

Metered billing rather than a committed weekly block, because the old
"recurring CoinPay invoice" copy documented a mechanic that never existed:
/api/payments/create makes a single one-shot payment, not a subscription.

- coinpay-checkout derives amount_usd from hours x 400 instead of a hardcoded
  250, validates hours as quarter-hour increments at or above the minimum, and
  returns 422 before calling CoinPay on bad input. Payment metadata carries
  billing/hours/rate_usd_per_hour in place of interval.
- project-request returns a rate, billing mode, and minimum; no amount exists
  until hours are approved.
- CoinPay config block documents COINPAY_RATE_USD_PER_HOUR / COINPAY_BILLING /
  COINPAY_MINIMUM_HOURS instead of a weekly amount and interval.
- New real /terms route replacing the SPA stub: what is billable, the
  approve-then-invoice flow, the minimum, cancellation on one week's notice,
  and an explicit clause that existing engagements keep their terms until both
  sides agree in writing.

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

* fix(mcp): advance prd_next_id expectation to 0003 for PRD 0002

The standards test asserts prd_next_id against the live prd/ directory, so
adding prd/0002-hourly-hire-us-rate.md moves the next free id to 0003. This
assertion advances with every PRD added to the repo.

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

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 10:34:49 -07:00
da5f6f8381
feat(openontology): Phase 2 + Phase 3 — storage, REST/SSE, MCP, RDF/SHACL, adapters, TUI, explorer (#101)
Some checks are pending
CI / build (push) Waiting to run
test / test (push) Waiting to run
Everything the two shipped PRD phases deferred, minus what is called out below.

Storage (Phase 2)
  @logicsrc/openontology gains a SQLite/Turso adapter. It hydrates the read
  model at open, serves reads synchronously — a query evaluator that awaits per
  triple pattern is unusable — and buffers mutations as SQL that flush() writes
  in one transaction. Versioned idempotent migrations; indexes over subject,
  predicate, entity-valued object, status, both time axes, aliases, and external
  ids; FTS5 for label/alias search. The append-only status log is replayed on
  open, so retractions, supersessions, and merge redirects survive a reopen.

REST + SSE + OpenAPI (Phase 2)
  16 paths under /api/ontologies in logicsrc-web, described at
  /api/ontologies/openapi and referencing the published JSON Schemas rather
  than restating them. No token is read-only; a curator token can apply; an
  agent token can propose and cannot apply. Idempotency-Key on mutations,
  revision ETags, 409 on a stale base revision, and an SSE stream that emits
  the same event objects as the JSON endpoint.

MCP (Phase 2)
  OpenOntology and OpenPRD surfaces on the standards server: spec/manifest/
  schema/queries and PRD spec/index as resources, 11 ontology tools and 6 PRD
  tools, 7 prompts. Read-only by default; OPENONTOLOGY_MCP_WRITABLE=1 buys
  proposals, never applies — the denial is the shared policy layer, not a
  second rule that could drift.

Interoperability (Phase 3)
  RDF/Turtle export and import of the reified profile, plus the plain triple
  for asserted relationships so a consumer wanting only the accepted graph gets
  one. SHACL for 5 of 7 constraint kinds; `unique` and `query` are reported as
  unmapped in both the return value and the generated Turtle, because a shape
  that quietly means something narrower is worse than no shape.

Source adapters (Phase 3)
  CSV, JSON, YAML, NDJSON, Markdown, generic JSON HTTP, and GitHub. All produce
  PROPOSED change-set operations with source, evidence selector, run id, and
  confidence attached; fetch is injected so ingestion is offline and testable.
  Each declares its capabilities, so "nothing was deleted upstream" is never
  confused with "this adapter cannot see deletions" — none of the seven can.

TUI + explorer
  Keyboard-first panels (types, entities, claims, sources, queries, change
  sets, validation, audit) as plain strings that survive SSH and 60 columns;
  status is a glyph and a word, never colour alone; the key bar wraps rather
  than truncating. Wired as `logicsrc ontology tui`. A read-only web explorer
  at /openontology/explore with entity and claim views showing status, both
  clocks, confidence, sources, evidence, and append-only history — plus an
  /openprd page for the companion standard.

Bugs found and fixed while testing
  - the API built a new engine per request, so `explain` could never find a
    resultId from a prior request; engines are now cached per role
  - the TUI status bar called engine.validateOntologyPackage(), appending a
    package.validated event on every repaint; it now uses the pure validator

Verification: 76 new tests (527 total across the monorepo, all passing); full
build green; the libSQL adapter is exercised against real files, the API
through its route handlers, and MCP over an in-memory transport.

Not included: PWA review/approval write flows (they need an auth story this
deployment does not have), OWL/RDFS mappings, SPARQL/Cypher/Datalog query
adapters, and Phase 4 governed actions. The compatibility matrix marks those
"planned", not "supported".

Refs: prd/0001-add-logicsrc-openontology-spec.md

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 05:10:33 -07:00
phucnguyen1707
59013cf0af
Sanitize rendered web content (#77) 2026-06-15 01:34:44 -07:00
phucnguyen1707
14fe9d608f
Require CoinPay userinfo identity (#21) 2026-06-13 23:01:15 -07:00
Autowebassat-blip
e89c10cc80
Reject malformed CoinPay webhook signatures (#41)
* Reject malformed CoinPay webhook signatures

* Fix webhook signature type guard

---------

Co-authored-by: Codex Microtask Operator <codex-microtask@example.com>
2026-06-13 22:56:12 -07:00
Autowebassat-blip
055cc09d14
Fallback invalid CoinPay checkout amounts (#42)
Co-authored-by: Codex Microtask Operator <codex-microtask@example.com>
2026-06-13 22:55:53 -07:00
Autowebassat-blip
9ed98ceaf7
Accept spaced CoinPay signature parts (#17) 2026-06-11 21:04:41 -07:00
Autowebassat-blip
d558554da3
Reject extra session token segments (#18) 2026-06-11 21:04:25 -07:00
f0a9f3890e Migrate logicsrc-web from Vite SPA to Next.js 16 App Router
Replaces the Vite single-page app + custom Node server.js with a Next.js
16.2.6 App Router app.

- proxy.ts (src/proxy.ts): www.logicsrc.com -> logicsrc.com 301 over https,
  preserving path + query (the original request, now via Next 16 Proxy).
- One SSR page via an optional catch-all ([[...slug]]) that renders the same
  marketing/spec page for each known top-level route (/docs, /blog, /openspec,
  ...) and 404s unknown paths, preserving existing canonical URLs. Markup is a
  faithful server-rendered port of the old main.ts (SEO upgrade over the prior
  client render); interactivity (hire-us form, CoinPay button, section scroll)
  moves to a client component.
- API routes ported to app/api/**: hire-us coinpay-checkout + project-request,
  oauth/coinpay start/callback/session, webhooks/coinpay. Shared logic in
  src/lib/coinpay.ts (eligibility, payment-rail selection, webhook verify,
  HMAC session sign/verify, cookies).
- commandboard-api (/health + /api/boards|tasks|plugins/*) is no longer mounted
  in-process; next.config.ts proxies those paths to COMMANDBOARD_API_URL via
  afterFiles rewrites (our own /api routes match first).
- Build/start switch to next build / next start. Contract tests rewritten to
  exercise proxy.ts, the route handlers, and pure helpers directly (21 passing);
  Playwright webServer updated.

Deployment (Railway): set COMMANDBOARD_API_URL to the commandboard-api service
URL and run it as its own service; root start now runs next start.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 03:41:48 +00:00
b1d8fe475a feat: add c0mpute plugin and hire-us request flow 2026-06-06 19:42:00 +00:00
a0314eb774 Add credential sharing openspec 2026-06-06 18:47:41 +00:00
de517ba9b7 Add LogicSRC hire us page 2026-06-06 17:35:22 +00:00
8e6124d23a Add LogicSRC web contract and E2E tests 2026-06-06 16:59:29 +00:00