Commit Graph

7 Commits

Author SHA1 Message Date
6ac0e1ff47 visuals: print styles for the wall and the diagrams, and Phase 7 notes
- Diagrams carry a print style block, so they print as ink on white rather than
  as dark panels; the client wall and the chips go white with a hairline.
- docs/phase-7-notes.md records what batch 1 shipped, how to add a mark or an
  image, and the Lighthouse measurements taken after the batch (100/100/100/100,
  CLS 0, mobile and desktop).

(cherry picked from commit ae9282e5f62b8c7ee149ebf96f8d3f00067a49e2)
2026-10-28 15:56:12 +11:00
Sam Rolfe
df864cc29e deploy: health gate and shape assertion follow the LAN publish address
Once the port is published on 192.168.20.13 the host no longer listens on
127.0.0.1:8096, so wait_healthy(), do_status() and the rollback path would all
get connection-refused and every deploy would roll back. They now probe
$PUBLISH_IP (RESUME_PUBLISH_IP, default 192.168.20.13). assert_shape() asserts
the published host IP is that address instead of loopback; the mem_limit ==
memswap_limit checks are unchanged. check_port stays address-agnostic on
`sport = :8096`.

Records the amendment in reference/stack.md (ports table + the bind rule) and
docs/phase-3-deploy.md (§3.2 bullet, flow diagram, DoD line), citing Sam's
decision of 2026-10-26, interaction 54aeb1a2. AGENTS.md is Sam's to change and
is untouched.
2026-10-26 22:40:22 +11:00
Sam Rolfe
5c0622c1b1 Ingestion redesigned: harvest from the estate, not just content/
- docs/phase-4-corpus.md rewritten: Gitea (all repos), vault via Gitea, Graphify
  graph, curated content as tier 1. Platform guides are config and public copy.
- docs/phase-5-ai-overlay.md: citations to originals, tier preference, live
  source readout.
- Board: AUD-144 (index content/ only) retired; AUD-147 replaces it, blocked by
  AUD-141 and AUD-142. AUD-145 relinked to AUD-143 and AUD-147.
2026-10-26 22:16:33 +11:00
f9dc574172 Phase 4: corpus and retrieval — chunks, Qdrant, FTS5, freshness audit
Satisfies docs/phase-4-corpus.md. content/ stays the single source of truth:
one pass over it writes both indexes, so the static pages and the retrieval
corpus cannot drift.

- corpus/: stdlib-only pipeline. validate -> chunk -> enrich -> embed -> upsert.
  Chunking is block-based, so a boundary cannot fall inside a fenced block, a
  table or front-matter (verified structurally, not by inspection).
- Deterministic ids: sha256(source_path + chunk_index + content_hash), rendered
  as a UUID. Re-running updates points; re-chunking deletes the old ones by
  source filter, so duplicates and orphans are both impossible.
- Incremental by content hash against a SQLite manifest. A provider, dimension
  or chunker change is refused instead of mixed: it needs a rebuild.
- Payloads per section 4.2 plus provenance, validated before any vector is
  written; a missing field fails the run and names the document and chunk.
- SQLite FTS5 over chunks (the keyword half of hybrid retrieval, decision D10)
  with area/confidence filters and a `terms` column so front-matter tech and
  tags are findable.
- Freshness audit: stale documents, due soon, index drift, contract drift;
  optional Apprise alert; exit code for Prefect.
- Embeddings behind one interface: omniroute (OpenAI-compatible, retries, key
  from the environment only) and local-hashing (offline placeholder). The
  provider decision is still Sam's; the pipeline does not depend on it.
- deploy/qdrant.yml: mem_limit = memswap_limit = 400m, loopback only.
- docs/phase-4-notes.md: operator manual, DoD evidence, measured memory.
- 76 unit tests, no container and no network.

Measured, Qdrant 1.20.0 under a 400 m cap at 1024 dimensions: 500 / 5,000 /
20,000 chunks settle at 128 / 138 / 151 MiB, peaking at 149 / 305 / 292 MiB
during ingest. Qdrant's default settings are OOM-killed between 5,000 and
20,000, so the collection is created with HNSW and payloads on disk; recorded in
reference/stack.md with the ceiling and the escalation order.

Note: the `make corpus*` targets were swept into the Phase 3 deploy commit
24590cc by concurrent work in this tree; the Makefile content is correct, and
this commit contains the pipeline they call.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-26 21:04:52 +11:00
Documenter
00fa15f98f Phase 1: content source of truth — 40 documents across six areas
Satisfies the Phase 1 Definition of Done:

- content/ validates cleanly against the frozen schema. `make validate`
  reports OK: 40 document(s) validated, 0 violations.
- Six areas exist, each with an L1 entry: ai-overview, platform-overview,
  edge-overview, products-overview, history-overview, about-overview.
- All six areas have an L2 entry: ai-systems, platform-estate, edge-fleet,
  products-business, history-engagements, about-narrative.
- 28 L3 artefact stubs under content/<area>/l3/. Every artefacts[].url in
  every document resolves to one of them; the validator proves there are no
  dangling references (and a deliberately broken copy exits 1).
- Every metric value traces to a source line in the evidence notes or the
  approved metric set in reference/content-map.md (per-metric citations are
  recorded in the AUD-131 completion comment).
- Every document carries confidence and last_verified=2026-10-26; the
  validator rejects a missing or non-canonical value.
- docs/content-redaction.md records the redaction pass: identifiers, third
  party personal data, credentials and infrastructure detail excluded, with
  reasons, plus the two numbers that are reported rather than smoothed.

Honesty positions held: 3 businesses active (12 adoptions over time),
Where-Woof deployed and pre-market, failures kept in (edge-failures), no
promotion of in-progress work to delivered.

No site code, no templates, no CSS, no rendering (Phase 2).
2026-10-26 17:30:35 +11:00
0eb151117e Phase 1a: content schema validator (freeze the schema)
Implements AGENTS.md section 7 front-matter schema as a single-file,
standard-library-only Python validator; no third-party YAML dependency
and no framework. Adds the `make validate` gate, a 20-case fixture set
and docs/content-schema.md.

DoD satisfied:
- make validate runs and exits 0 on an empty/clean content/ tree
  (missing dir and empty dir both exit 0; fixture ok-empty covers it).
- Every violation class has a fixture under test/fixtures/fail-*; each
  exits non-zero with one line per violation (file:line: field: rule).
  `make test` runs all 20 cases: 20/20 pass.
- Dangling artefact reference is fatal (fail-dangling-artefact;
  artefacts[].url must resolve to an existing in-repo L3 stub or asset).
- Unknown front-matter field is fatal (fail-unknown-field), including
  unknown keys nested inside artefacts[]/metrics[].
- docs/content-schema.md committed; states the frozen schema, links to
  AGENTS.md section 7, and records that any later schema change is a
  breaking change requiring Sam's approval.
- Scope respected: no content authored, no rendering, no site code.

Files: Makefile, tools/validate_content.py, test/fixtures/**,
docs/content-schema.md, .gitignore (__pycache__).
2026-10-26 17:26:00 +11:00
Sam Rolfe
b267e55f8c Replace Vite/React scaffold with Go build spec
- AGENTS.md: build spec for Paperclip (constraints, conventions, 7 phases)
- docs/phase-1..7: per-phase work, DoD, out-of-scope, risks
- reference/: frozen decisions, stack+ports+budgets, content map, acceptance tests
- agents/: persona and security policy drafts
- Retires the React scaffold; history retained as record of the false start
2026-10-26 16:02:35 +11:00