diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 117714a..dc54f48 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,121 +1,187 @@ -# Clone the repository + -git clone https://github.com/hyperpolymath/language-bridges.git +# Contributing to blocky-writer + +**Read `README.adoc` first.** The short version of where this project stands: +the Rust/WASM core (`rust/pdftool_core`) is implemented, unit-tested and green +in CI. The AffineScript frontend (`src/*.affine`) is a prototype with no build +pipeline in this checkout. Nothing here is release-ready as a Firefox extension +yet. + +--- + +## Clone and set up + +```bash +git clone https://github.com/hyperpolymath/blocky-writer.git cd blocky-writer +``` -# Using Guix (recommended for reproducibility) +You need **Rust stable** with the `rustfmt` and `clippy` components. Nothing else +is required for the only checks that exist: -guix develop +```bash +rustup toolchain install stable --component rustfmt clippy +``` + +There is **no** Node, Deno, npm, `wasm-pack` or Guix requirement. Older documents +in this repository describe a different project shape — if a file tells you to +run `deno task`, `just check`, or `guix develop`, it is stale. Please report it +with the *Documentation* issue template. -# Or using toolbox/distrobox +### Optional tooling in the tree -toolbox create language-bridges-dev -toolbox enter language-bridges-dev -# Install dependencies manually +| File | What it is | +| --- | --- | +| `Justfile`, `contractile.just` | `just` recipes: `just doctor`, `just tour`, `just help-me`, `just aspect`, `just crg-grade`. Run `just --list` for the current set. | +| `mise.toml`, `.tool-versions` | Tool version pinning. | +| `Containerfile`, `stapeln.toml`, `selur-compose/compose.toml` | Container and compose definitions. | +| `setup.sh` | Bootstrap script. | +| `scripts/build-wasm.sh` | Builds the WASM package. Needs `wasm-pack` + `wasm32-unknown-unknown`. Nothing in CI runs it and nothing consumes the output yet. | -# Verify setup +Several of these were minted from `hyperpolymath/rsr-template-repo` and describe +a project shape this repository does not have. Treat them as scaffolding. -just check # or: cargo check / mix compile / etc. -just test # Run test suite +--- -### Repository Structure +## Repository structure ```text blocky-writer/ -├── src/ # Source code (Perimeter 1-2) -├── lib/ # Library code (Perimeter 1-2) -├── extensions/ # Extensions (Perimeter 2) -├── plugins/ # Plugins (Perimeter 2) -├── tools/ # Tooling (Perimeter 2) -├── docs/ # Documentation (Perimeter 3) -│ ├── architecture/ # ADRs, specs (Perimeter 2) -│ └── proposals/ # RFCs (Perimeter 3) -├── examples/ # Examples (Perimeter 3) -├── spec/ # Spec tests (Perimeter 3) -├── tests/ # Test suite (Perimeter 2-3) -├── .well-known/ # Protocol files (Perimeter 1-3) -├── .github/ # GitHub config (Perimeter 1) -│ ├── CONTRIBUTING.md # This file -│ ├── ISSUE_TEMPLATE/ -│ └── workflows/ -├── CHANGELOG.md -├── CODE_OF_CONDUCT.md -├── GOVERNANCE.md -├── LICENSE -├── MAINTAINERS.md -├── README.adoc -├── SECURITY.md -├── flake.guix # Guix flake (Perimeter 1) -└── justfile # Task runner (Perimeter 1) +├── rust/pdftool_core/ # Rust → WASM core (the only tested code) +│ ├── src/lib.rs # detect_blocks, fill_blocks, BW_* taxonomy +│ ├── Cargo.toml +│ └── Cargo.lock # committed; CI runs with --locked +├── src/ # AffineScript prototype (not buildable here) +│ ├── popup.affine, content.affine, background.affine +│ ├── components/ # Block.affine, FormFiller.affine +│ └── core/ # PdfTool, ProvenMount, Storage +├── public/ # manifest.json, popup.html, icons +├── tests/ # aspect + fuzz placeholder +├── scripts/ # build-wasm.sh, check-lock-sync.sh +├── wiki/ # BerryWiki-format wiki source (see wiki/README.adoc) +├── docs/ +│ ├── ci/CHECK-DETERMINATIONS.adoc # the CI ledger — read the standing rules +│ ├── ecosystem/ECOSYSTEM.adoc # suite boundary and neighbours +│ └── reports/, tech-debt-*.adoc +├── .machine_readable/ # machine-readable state; load-bearing, do not restructure +├── www/.well-known/ # ai.txt, humans.txt, security.txt +├── README.adoc # the README (AsciiDoc, not Markdown) +├── TOPOLOGY.adoc # architecture map + completion dashboard +├── EXPLAINME.adoc +├── TEST-NEEDS.adoc # CRG test grade +├── CHANGELOG.adoc +├── CODE_OF_CONDUCT.adoc +├── SECURITY.adoc +├── GOVERNANCE.adoc +├── Containerfile +├── Justfile +└── .github/ + ├── ISSUE_TEMPLATE/ # bug_report, feature_request, documentation, config + ├── PULL_REQUEST_TEMPLATE.md + ├── workflows/ + └── actions.lock ``` - --- +Note the `.adoc` extensions. This repository documents itself in AsciiDoc, not +Markdown. + +--- + +## How to contribute -## How to Contribute +### Reporting bugs -### Reporting Bugs +Use the [bug report template](.github/ISSUE_TEMPLATE/bug_report.yml). Include: - **Before reporting**: - 1. Search existing issues - 2. Check if it's already fixed in `main` - 3. Determine which perimeter the bug affects +* Which area — Rust core, frontend prototype, CI, docs or packaging. +* Steps to reproduce. For core bugs, a minimal PDF and the field map you passed. +* The **whole** error payload if you got one. Core failures carry a stable + machine code plus message and context; the code alone is not enough. - **When reporting**: +Before reporting, search existing issues and check whether the bug is in the +core (actionable) or the frontend prototype (may not be). - Use the [bug report template](.github/ISSUE_TEMPLATE/bug_report.md) and include: +### Suggesting features - - Clear, descriptive title - - Environment details (OS, versions, toolchain) - - Steps to reproduce - - Expected vs actual behaviour - - Logs, screenshots, or minimal reproduction +Use the [feature request template](.github/ISSUE_TEMPLATE/feature_request.yml). +Check `docs/ecosystem/ECOSYSTEM.adoc` first — blocky-writer owns fixed-layout PDF +and application-form placement *only*. Viewing, editing, conversion, OCR and +print routing belong to other projects in the suite. -### Suggesting Features +### Reporting documentation problems - **Before suggesting**: - 1. Check the [roadmap](ROADMAP.md) if available - 2. Search existing issues and discussions - 3. Consider which perimeter the feature belongs to +Use the [documentation template](.github/ISSUE_TEMPLATE/documentation.yml). +Documentation drift is a defect here, not a nit. - **When suggesting**: +### Security - Use the [feature request template](.github/ISSUE_TEMPLATE/feature_request.md) and include: +Do **not** open a public issue. Use +[GitHub Security Advisories](https://github.com/hyperpolymath/blocky-writer/security/advisories/new). +See `SECURITY.adoc`. - - Problem statement (what pain point does this solve?) - - Proposed solution - - Alternatives considered - - Which perimeter this affects +### Opening a pull request -### Your First Contribution +1. Fork and branch from `main`. +2. Make your change. +3. Run the three core checks — **all three must pass**: - Look for issues labelled: + ```bash + cargo fmt --manifest-path rust/pdftool_core/Cargo.toml -- --check + cargo test --manifest-path rust/pdftool_core/Cargo.toml --locked + cargo clippy --manifest-path rust/pdftool_core/Cargo.toml --locked --all-targets -- -D warnings + ``` - - [`good first issue`](https://github.com/hyperpolymath/language-bridges/labels/good%20first%20issue) — Simple Perimeter 3 tasks - - [`help wanted`](https://github.com/hyperpolymath/language-bridges/labels/help%20wanted) — Community help needed - - [`documentation`](https://github.com/hyperpolymath/language-bridges/labels/documentation) — Docs improvements - - [`perimeter-3`](https://github.com/hyperpolymath/language-bridges/labels/perimeter-3) — Community sandbox scope + `cargo test` runs 6 tests. If you get a different number, something changed + and the wiki is stale — fix the wiki too. - --- + If you cannot run these — no Rust toolchain, no crates.io access — **say so + explicitly in the PR** rather than implying you did. CI is the only authority + on green. -## Development Workflow +4. **If you changed a `uses:` line in any workflow**, regenerate + `.github/workflows/actions.lock` in the *same commit* and run + `scripts/check-lock-sync.sh` (needs `gawk`). A stale lock entry is as fatal as + a missing one, and the failure is silent — `startup_failure`, zero jobs, no + log. +5. **If you removed or retired a CI check**, add or update a row in + `docs/ci/CHECK-DETERMINATIONS.adoc`. +6. Fill in `.github/PULL_REQUEST_TEMPLATE.md`. Do not delete the checklist. -### Branch Naming +### House rules -docs/short-description # Documentation (P3) test/what-added # Test -additions (P3) feat/short-description # New features (P2) -fix/issue-number-description # Bug fixes (P2) refactor/what-changed # -Code improvements (P2) security/what-fixed # Security fixes (P1-2) +* AsciiDoc (`.adoc`) for repository documentation. SPDX header on every file. +* MPL-2.0 licence, Palimpsest philosophy. +* Conventional commits: `fix(rust): …`, `docs(ci): …`, `ci: …`. +* No new TypeScript, Python or Go. No npm/bun/yarn/pnpm dependencies. +* No `unsafe` blocks in Rust without a safety comment. The core is + `#![forbid(unsafe_code)]` — keep it that way. +* `.machine_readable/` is load-bearing. Do not restructure it casually. +* `BW_*` error codes are stable API. Adding or renaming one is a breaking change. +* **Never** silence a gate. No `continue-on-error`, no `if: false`, no quiet + deletion of a job. +### CI you cannot trigger -### Commit Messages +Every Actions run whose actor is `arena-ai-coding-agent[bot]` is refused at +startup (`Actor is not allowed to trigger Actions workflows`). A bot-authored PR +shows **no** repository checks at all — not red, absent — because a startup +failure creates no check run. This is an org-side policy; no file change cures +it. Bot PRs must be merged by the repository owner so the merge push carries an +allowed actor. See the `<>` section of `docs/ci/CHECK-DETERMINATIONS.adoc`. - We follow [Conventional Commits](https://www.conventionalcommits.org/): +--- -type(scope): description +## The wiki -Body: what changed and why. +The project wiki lives at + in BerryWiki format. Its +source of truth is `wiki/` in this repository. See `wiki/README.adoc` for how to +edit and publish it. -Footer: issue reference, e.g. Closes #123 -\[optional body\] +## Questions -\[optional footer\] +Open an issue, or see `GOVERNANCE.adoc` for how decisions are made. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..638b044 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,116 @@ +# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell +# SPDX-License-Identifier: MPL-2.0 +# Bug report issue template for hyperpolymath/blocky-writer +name: Bug Report +description: Create a report to help us improve +title: "[Bug]: " +labels: ["bug", "priority:p2"] +assignees: [] +body: + - type: markdown + attributes: + value: | + Thank you for taking the time to report a bug. Please fill out the sections below + so we can reproduce and fix the issue. + + **Before filing:** check whether the bug is in the Rust core or in the + AffineScript frontend prototype. Only the Rust core is implemented and + tested today; the frontend has no build pipeline, so frontend bugs may + not be actionable. + + - type: dropdown + id: area + attributes: + label: Which area? + description: Pick the closest match. Used for triage only. + options: + - "rust-core — rust/pdftool_core (detect_blocks / fill_blocks)" + - "rust-core — error taxonomy (BW_* codes)" + - "frontend — src/*.affine prototype (no build pipeline)" + - "ci — workflows, actions.lock, gates" + - "docs — README, wiki, docs/" + - "packaging — Containerfile, manifest, selur-compose" + validations: + required: true + + - type: textarea + id: description + attributes: + label: Describe the bug + description: A clear and concise description of what the bug is. + placeholder: When I do X, Y happens instead of Z. + validations: + required: true + + - type: textarea + id: reproduction + attributes: + label: Steps to reproduce + description: Detailed steps to reproduce the behavior. A minimal PDF and field map is ideal. + placeholder: | + 1. Load a PDF with an AcroForm containing ... + 2. Call `fill_blocks(pdf, blocks, { "Name": "Ada" })` + 3. The returned PDF has ... + value: | + 1. + 2. + 3. + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected behavior + description: A clear and concise description of what you expected to happen. + validations: + required: true + + - type: textarea + id: environment + attributes: + label: Environment + description: Versions and platform. For core bugs, the Rust toolchain and lopdf version matter. + placeholder: | + - OS: + - Rust: + - blocky-writer commit: + - Firefox version (if frontend): + value: | + - OS: + - Rust: + - blocky-writer commit: + validations: + required: false + + - type: textarea + id: error-code + attributes: + label: Error code, if any + description: | + Core failures carry a stable machine code (`BW_*`) plus a message and + optional context. Paste the whole payload — the code alone is not enough. + placeholder: | + { "code": "BW_FILL_NO_MATCHING_FIELDS", "message": "...", "context": "..." } + validations: + required: false + + - type: textarea + id: logs + attributes: + label: Logs or output + description: Any relevant output. For CI failures, link the run. + validations: + required: false + + - type: checkboxes + id: checks + attributes: + label: Pre-flight + options: + - label: I searched existing issues and this is not a duplicate. + required: true + - label: I ran the three core checks (`cargo fmt --check`, `cargo test --locked`, `cargo clippy -D warnings`) where applicable. + required: false + - label: I have read the current status in the repository README and understand the frontend is a prototype. + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..4c0fc49 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell +# SPDX-License-Identifier: MPL-2.0 +# Issue template chooser configuration for hyperpolymath/blocky-writer +blank_issues_enabled: true +contact_links: + - name: Project wiki + url: https://github.com/hyperpolymath/blocky-writer/wiki + about: BerryWiki-format wiki — architecture, Rust core, CI gates, ecosystem and glossary. Source of truth is wiki/ in this repository. + - name: Ecosystem boundary + url: https://github.com/hyperpolymath/docmatrix/issues/71 + about: The versioned composition contract for the precision document suite, and where each project's boundary is declared. + - name: Security vulnerabilities + url: https://github.com/hyperpolymath/blocky-writer/security/advisories/new + about: Report security vulnerabilities privately via GitHub Security Advisories. Do not open a public issue. diff --git a/.github/ISSUE_TEMPLATE/documentation.yml b/.github/ISSUE_TEMPLATE/documentation.yml new file mode 100644 index 0000000..0ea0a06 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation.yml @@ -0,0 +1,57 @@ +# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell +# SPDX-License-Identifier: MPL-2.0 +# Documentation issue template for hyperpolymath/blocky-writer +name: Documentation +description: Report wrong, missing or stale documentation +title: "[Docs]: " +labels: ["documentation"] +assignees: [] +body: + - type: markdown + attributes: + value: | + Use this for anything in `README.adoc`, `TOPOLOGY.adoc`, `docs/`, the + wiki, or `.github/` that is wrong, missing or out of date. + + Documentation drift is treated as a defect here, not a nit. If a document + told you something untrue about the state of the project, that is a bug + in the document. + + - type: dropdown + id: kind + attributes: + label: What kind of problem? + options: + - "Stale — describes a state that is no longer true" + - "Wrong — describes something that was never true" + - "Missing — the information does not exist anywhere" + - "Contradictory — two documents disagree" + - "Unfindable — exists but is not linked from where you looked" + validations: + required: true + + - type: input + id: location + attributes: + label: Which file or page? + description: Path in the repository, or the wiki page name. + placeholder: "TOPOLOGY.adoc — Completion Dashboard section" + validations: + required: true + + - type: textarea + id: problem + attributes: + label: What is wrong? + description: Quote the offending text if you can. + placeholder: "It says the Popup UI is 100% complete, but there is no build pipeline for it." + validations: + required: true + + - type: textarea + id: correction + attributes: + label: What should it say? + description: If you know. If you do not, say so — that is useful information too. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..53d86df --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,83 @@ +# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell +# SPDX-License-Identifier: MPL-2.0 +# Feature request issue template for hyperpolymath/blocky-writer +name: Feature Request +description: Suggest an idea or enhancement for this project +title: "[Feature]: " +labels: ["enhancement", "priority:p2"] +assignees: [] +body: + - type: markdown + attributes: + value: | + Thank you for suggesting a feature. Please describe your idea clearly so we can + evaluate and prioritize it. + + **Before filing:** check the boundary statement in + `docs/ecosystem/ECOSYSTEM.adoc`. blocky-writer owns fixed-layout PDF and + application-form placement only. Viewing, editing, conversion, OCR and + print routing belong to other projects in the suite — if your idea is + one of those, it probably belongs there instead. + + - type: textarea + id: problem + attributes: + label: Problem statement + description: Is your feature request related to a problem? Describe the pain point. + placeholder: "I'm always frustrated when [...]. Currently there is no way to [...]." + validations: + required: true + + - type: textarea + id: solution + attributes: + label: Proposed solution + description: A clear and concise description of what you want to happen. + placeholder: "I'd like a command/option/feature that [...]." + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives considered + description: Any alternative solutions or features you have considered. + placeholder: "I considered using X, but it doesn't work because [...]." + validations: + required: false + + - type: dropdown + id: scope + attributes: + label: Which layer? + options: + - "rust-core — rust/pdftool_core" + - "frontend — src/*.affine prototype" + - "packaging / extension build" + - "ci / governance" + - "docs / wiki" + - "not sure" + validations: + required: false + + - type: textarea + id: boundary + attributes: + label: Boundary check + description: | + Does this belong to blocky-writer, or to another project in the suite? + If another, name it and say why. This is not a blocker, but it speeds + triage considerably. + placeholder: "This belongs here because ... / This may belong to docmatrix because ..." + validations: + required: false + + - type: checkboxes + id: checks + attributes: + label: Pre-flight + options: + - label: I searched existing issues and discussions and this is not a duplicate. + required: true + - label: I have read `docs/ecosystem/ECOSYSTEM.adoc` and believe this is in scope. + required: false diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..9fd79a3 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,52 @@ + + +## What changed + + + +## Type of change + +- [ ] Bug fix (`fix:`) +- [ ] New feature (`feat:`) +- [ ] Documentation (`docs:`) +- [ ] CI / workflow / lockfile (`ci:`) +- [ ] Refactor, no behaviour change (`refactor:`) +- [ ] Chore (`chore:`) + +## Local verification + + + +```bash +cargo fmt --manifest-path rust/pdftool_core/Cargo.toml -- --check +cargo test --manifest-path rust/pdftool_core/Cargo.toml --locked +cargo clippy --manifest-path rust/pdftool_core/Cargo.toml --locked --all-targets -- -D warnings +``` + +## Checklist + +- [ ] I ran the three commands above (or explained why I could not). +- [ ] **If I changed a `uses:` line**, `actions.lock` is updated in this same commit and I ran `scripts/check-lock-sync.sh`. +- [ ] **If I removed or retired a CI check**, there is a matching row in `docs/ci/CHECK-DETERMINATIONS.adoc`. +- [ ] I have not added `continue-on-error`, `if: false`, or weakened any gate. +- [ ] If I changed a component's state, `TOPOLOGY.adoc` is updated. +- [ ] If I changed something the wiki asserts, the matching `wiki/` page is updated. +- [ ] Documentation that this PR makes stale has been updated in the same PR. + +## Owner actions + + + +- [ ] Merge as the repository owner, not via the bot. Runs triggered by + `arena-ai-coding-agent[bot]` are refused at startup + (`Actor is not allowed to trigger Actions workflows`), so a bot-authored PR + shows **no** repository checks at all — not red, absent. + +## Notes for the reviewer + + diff --git a/.machine_readable/6a2/ECOSYSTEM.a2ml b/.machine_readable/6a2/ECOSYSTEM.a2ml index 2840c66..386b989 100644 --- a/.machine_readable/6a2/ECOSYSTEM.a2ml +++ b/.machine_readable/6a2/ECOSYSTEM.a2ml @@ -1,6 +1,10 @@ # SPDX-License-Identifier: MPL-2.0 # ECOSYSTEM.a2ml — Ecosystem position # Converted from ECOSYSTEM.scm on 2026-03-15 +# Expanded 2026-09-27 to carry the suite boundary, so machine readers get it +# without parsing prose. The authoritative, versioned contract is +# https://github.com/hyperpolymath/docmatrix/issues/71 — if this file and that +# issue disagree, the issue wins and this file is stale. [metadata] project = "blocky-writer" @@ -8,3 +12,43 @@ ecosystem = "hyperpolymath" [position] type = "component" +suite = "precision document suite" +contract = "https://github.com/hyperpolymath/docmatrix/issues/71" +contract-owner = "hyperpolymath/docmatrix" + +[boundary] +owns = "fitting and placement into fixed-layout PDF and application-form boxes, baselines and per-character cells designed for hand spacing" +does-not-own = [ + "multi-format viewing and editing — hyperpolymath/formatrix-docs", + "multi-format conversion and precision coordination — hyperpolymath/docmatrix", + "OCR, NER and metadata extraction — hyperpolymath/docudactyl", + "print routing — hyperpolymath/presswerk", + "cross-document consistency reconciliation — hyperpolymath/recon-silly-ation", + "capability-bounded critical execution — ForthWall, proposed and unbuilt", +] +hard-constraint = "never silently normalise page geometry — composition contract clause 4" + +[suite] +docmatrix = "multi-format conversion and precision coordination" +formatrix-docs = "tabbed multi-format viewing and editing" +blocky-writer = "fixed-layout PDF and application-form placement (this repo)" +forthwall = "proposed capability-bounded execution layer — not implemented" + +[adjacent] +affinescript = "hyperpolymath/affinescript — frontend language, real consumer" +docudactyl = "hyperpolymath/docudactyl — OCR/NER/metadata extraction" +dotmatrix-fileprinter = "hyperpolymath/dotmatrix-fileprinter — filesystem-side sibling" +presswerk = "hyperpolymath/presswerk — print routing, downstream of a filled PDF" +recon-silly-ation = "hyperpolymath/recon-silly-ation — cross-document reconciler" +universal-language-server-plugin = "hyperpolymath/universal-language-server-plugin — overlaps docmatrix's remit" +gv-clade-index = "hyperpolymath/gv-clade-index — taxonomy registry; CLADE.a2ml registered here" +deed-ecosystem = "hyperpolymath/deed-ecosystem — .deed manifest format" +standards = "hyperpolymath/standards — estate governance" +ddraig-ssg = "hyperpolymath/ddraig-ssg — Pages SSG (Idris 2), one of two, undecided" +casket-ssg = "hyperpolymath/casket-ssg — Pages SSG (Haskell), one of two, undecided" +berrywiki = "metadatastician/berrywiki — this project's wiki format and tooling" +rsr-template-repo = "hyperpolymath/rsr-template-repo — the template this repo was minted from" + +[communication] +norm = "each repo states its own boundary in its README and links the others; a short issue is filed on a neighbour when a status change unblocks or affects it" +no-standing-integration-programme = true diff --git a/.machine_readable/6a2/STATE.a2ml b/.machine_readable/6a2/STATE.a2ml index c68a393..16f7c54 100644 --- a/.machine_readable/6a2/STATE.a2ml +++ b/.machine_readable/6a2/STATE.a2ml @@ -1,14 +1,54 @@ # SPDX-License-Identifier: MPL-2.0 # STATE.a2ml — Project state checkpoint # Converted from STATE.scm on 2026-03-15 +# Reviewed and corrected 2026-09-27 — the completion percentage below was +# stale (it still read 0 from the initial conversion). It now reflects what is +# actually implemented and verified. TOPOLOGY.adoc carries the per-component +# breakdown; this file carries the headline. [metadata] project = "blocky-writer" version = "0.1.0" -last-updated = "2026-03-15" +last-updated = "2026-09-27" status = "active" [project-context] name = "blocky-writer" -completion-percentage = 0 -phase = "In development" +# Working, verified code only. The AffineScript frontend is a prototype with no +# build pipeline in this checkout and is counted as 0 despite having sources. +completion-percentage = 50 +phase = "In development — Rust core green, frontend prototype" + +[verified] +# Things with a command that proves them. +rust-core-fmt = "green (cargo fmt -- --check)" +rust-core-tests = "green (cargo test --locked, 6/6)" +rust-core-clippy = "green (cargo clippy --all-targets -- -D warnings)" +rust-core-sha = "e1b6225" +rust-core-run = 36296845297 +ci-rust-core-job = "green on main" +lock-sync-gate = "green on main" +governance = "green on main" +codeql = "green on main" + +[not-implemented] +# Counted as zero. Do not describe these as in progress without evidence. +extension-bundle-pipeline = "no AffineScript compiler config, no package manifest, no reproducible bundle (deno.json removed by #43, 2026-08-24)" +ruled-line-detection = "not implemented — the 'hand spacing' case the project is named for" +per-character-cell-detection = "not implemented" +baseline-detection = "not implemented" +signature-field-writeback = "not implemented (Tx / Ch / Btn only)" + +[known-red-on-main] +# Not blocky-writer defects, but they are red and they are not in the ledger yet. +hypatia-security-scan = "run 36296845360 — Hypatia Neurosymbolic Analysis job fails building the scanner and uploading SARIF" +mirror-to-git-forges = "run 36296845635 — mirror-disroot, mirror-gitea, mirror-codeberg, mirror-bitbucket fail; gitlab, sourcehut, radicle green" + +[open-decisions] +pages-ssg = "two workflows build the Pages site under one concurrency group: pages.yml (Ddraig/Idris2) and casket-pages.yml (casket-ssg/Haskell). Which is canonical is undecided." +required-status-checks = "Branch-Floor ruleset (id 23869449) carries no required_status_checks rule. Owner-side fix is pending." + +[ecosystem] +suite = "precision document suite" +contract = "https://github.com/hyperpolymath/docmatrix/issues/71" +siblings = "docmatrix (conversion), formatrix-docs (viewer/editor), ForthWall (proposed, unbuilt)" diff --git a/.machine_readable/INTENT.contractile b/.machine_readable/INTENT.contractile index 0a5def8..3301ae9 100644 --- a/.machine_readable/INTENT.contractile +++ b/.machine_readable/INTENT.contractile @@ -3,6 +3,16 @@ ; Helps LLM/SLM agents understand what this repo IS and IS NOT. ; ; Part of the contractile family: MUST, TRUST, DUST, INTENT, ADJUST +; +; Token fill: 2026-09-27. The seven {{...}} tokens this file inherited from +; hyperpolymath/rsr-template-repo were resolved from evidence in this +; repository and in the suite contract, not invented: +; MONOREPO_OR_STANDALONE — this is its own repository, not a workspace root. +; DEP1 / DEP2 — rust/pdftool_core/Cargo.toml. +; CONSUMER1 / CONSUMER2 — named as suite components in docmatrix#71. +; ONE_PARAGRAPH_* — derived from README.adoc and +; docs/ecosystem/ECOSYSTEM.adoc. +; REQUIRES_INITIALISATION.adoc records the fill. ; ── Definitions ────────────────────────────────────────────────── ; @@ -30,43 +40,85 @@ ; ── End Definitions ────────────────────────────────────────────── (intent-contractile - (version "1.0.0") + (version "1.1.0") (repo "blocky-writer") ; === Purpose (what this repo IS) === (purpose - "{{ONE_PARAGRAPH_PURPOSE}}" + "blocky-writer fills fixed-layout PDF and application forms — the kind laid + out for boxes, baselines and per-character cells that were designed for + hand spacing rather than reliable computer entry. It ships as a Mozilla + Firefox extension: a Rust core compiled to WebAssembly that detects widget + annotations and writes values back into the AcroForm, behind a thin + AffineScript frontend. Its contribution to the precision document suite is + placement into a form that already exists, not the creation or conversion + of the document." ) ; === Anti-Purpose (what this repo is NOT — prevents scope creep) === (anti-purpose - "{{ONE_PARAGRAPH_ANTI_PURPOSE}}" - ; Examples: - ; "This is NOT a general-purpose database — it solves one specific problem." - ; "This is NOT a framework — it is a library with a focused API." - ; "This does NOT handle authentication — that is delegated to [other repo]." + "This is NOT a document viewer or editor — tabbed multi-format viewing and + editing belongs to Formatrix Docs. It is NOT a conversion engine — that is + DocMatrix, and no lossy hub format (Microsoft Word or otherwise) is ever to + become mandatory here. It is NOT an OCR, NER or metadata-extraction + pipeline — that is Docudactyl. It is NOT a print router — that is + Presswerk. It is NOT a cross-document consistency reconciler — that is + recon-silly-ation. It is NOT a general-purpose PDF library: it does not + render, typeset or lay out pages, and it does not implement the proposed + ForthWall execution layer. It is NOT only for users with perfect vision, + hearing or mobility — the accessibility work in wokelangiser.toml is part + of the project, not an optional extra." ) ; === Key Architectural Decisions That Must Not Be Reversed === (architectural-invariants - ; *REMINDER: List the foundational decisions* - ; ("Idris2 for ABI definitions — dependent types prove interface correctness") - ; ("Zig for FFI — zero-cost C ABI compatibility") - ; ("Elixir for supervision — OTP fault tolerance") + ("Rust for the core, compiled to WASM — the PDF work is numeric and + security-relevant; a memory-safe language is the point, and + rust/pdftool_core is #![forbid(unsafe_code)]") + ("The WASM boundary is exactly two functions — detect_blocks and + fill_blocks. Everything else is private. Do not widen the surface + casually; each export is a permanent contract with the frontend") + ("Field writeback is NAME-driven, not coordinate-driven. fill_blocks keys + on AcroForm field names; the blocks argument is validated but not used to + place content. Reversing this would silently change what the tool means") + ("BW_* error codes are stable API. Failures cross the boundary as + structured {code, message, context} payloads, never as bare strings") + ("Page geometry is never silently normalised. This is clause 4 of the + composition contract in docmatrix#71, and geometry is this project's + whole subject — the temptation to 'tidy' a rectangle is the failure the + clause exists to prevent") + ("Deno is gone. deno.json and every deno task were deleted by #43 on + 2026-08-24; the leftover deno.lock is not a declaration of anything. + Do not reintroduce a JavaScript toolchain") ) ; === Sensitive Areas (if in doubt, ask) === (ask-before-touching - ; *REMINDER: List areas where LLMs should check before modifying* - ; "src/abi/ — formal proofs, changes require re-verification" - ; "ffi/zig/ — C ABI boundary, changes affect all language bindings" - ; ".machine_readable/ — checkpoint files, format is specified" + ".machine_readable/ — checkpoint and contractile files; the format is + specified by the estate and several gates read it" + ".github/workflows/actions.lock — must change in the same commit as any + uses: line it records, or GitHub refuses to start the workflow silently + (startup_failure, zero jobs, no log)" + "docs/ci/CHECK-DETERMINATIONS.adoc — the estate stopping-rule ledger. A + check may be retired or repaired, never muted" + "rust/pdftool_core/src/lib.rs public surface — detect_blocks, fill_blocks, + the Block struct and every BW_* code are external contract" + "www/.well-known/ — ai.txt, humans.txt and security.txt are externally + visible policy statements, not documentation" ) ; === Ecosystem Position === + ; Filled 2026-09-27 from docmatrix#71, which names blocky-writer as one of the + ; suite's user-facing components and carries the versioned composition + ; contract. If this file and docmatrix#71 disagree, docmatrix#71 wins. (ecosystem - (belongs-to "{{MONOREPO_OR_STANDALONE}}") - (depends-on ("{{DEP1}}" "{{DEP2}}")) - (depended-on-by ("{{CONSUMER1}}" "{{CONSUMER2}}")) + (belongs-to "standalone") + (depends-on ("lopdf" "wasm-bindgen")) + (depended-on-by ("docmatrix" "formatrix-docs")) + (contract "https://github.com/hyperpolymath/docmatrix/issues/71") + (note "blocky-writer is a component of the hyperpolymath precision document + suite, not a library it consumes. 'Depended-on-by' here names the + suite projects whose boundaries docmatrix#71 defines relative to + this one; no code-level dependency exists in either direction.") ) ) diff --git a/.machine_readable/agent_instructions/debt.a2ml b/.machine_readable/agent_instructions/debt.a2ml index c0238c5..e6fbe3e 100644 --- a/.machine_readable/agent_instructions/debt.a2ml +++ b/.machine_readable/agent_instructions/debt.a2ml @@ -6,44 +6,112 @@ # Becomes the next session's Phase 0 input. # # Reference: ADR-002 in standards/agentic-a2ml/docs/ +# +# Populated 2026-09-27 from the documentation-and-tooling recon. Every item +# below was FOUND and deliberately NOT FIXED — either because it needs a +# maintainer decision, or because it is outside the recon's remit. [metadata] -version = "1.0.0" -last-updated = "2026-03-24" - -# ============================================================================ -# DEBT ITEMS -# ============================================================================ -# Each item has: component, issue, effort (easy|medium|hard), impact (high|medium|low), -# priority (should|could), and discovered date. -# -# Items are consumed (removed) when fixed. New items are added at session end. -# The debt list prevents the "one more wave" loop — found things are persisted, -# not forgotten, and not used as justification for infinite meandering. +version = "1.1.0" +last-updated = "2026-09-27" +source = "2026-09-27 documentation/tooling recon" # ============================================================================ # SHOULD — would fix next wave # ============================================================================ -# These are inputs for the next session if the user says "keep going". -# -# Example: -# [[debt.should]] -# component = "system-tools/monitoring/observatory" -# issue = "Stale duplicate of root observatory/" -# effort = "easy" -# impact = "medium" -# discovered = "2026-03-23" + +[[debt.should]] +component = ".github/workflows" +issue = "Two workflows build the Pages site under one concurrency group: pages.yml (Ddraig SSG, Idris 2) and casket-pages.yml (casket-ssg, Haskell). They cancel each other. pages.yml also looks for README.md, which does not exist here (this repo uses README.adoc), so it would publish a bare '# hyperpolymath/blocky-writer' index. casket-pages.yml handles README.adoc correctly. Which one is canonical is an undecided owner call." +effort = "medium" +impact = "high" +discovered = "2026-09-27" +note = "Do not fix without an owner decision on which SSG wins. Any change needs the matching actions.lock change in the same commit, verified by scripts/check-lock-sync.sh (needs gawk)." + +[[debt.should]] +component = ".github/workflows/hypatia-scan.yml" +issue = "Hypatia Security Scan is red on main at e1b6225 (run 36296845360). The 'Hypatia Neurosymbolic Analysis' job fails at 'Build Hypatia scanner (if needed)' and 'Upload SARIF to GitHub code scanning'. It is not a blocky-writer defect, but it is red and it has no row in docs/ci/CHECK-DETERMINATIONS.adoc." +effort = "medium" +impact = "medium" +discovered = "2026-09-27" +note = "Needs a determination row before anyone touches it — the estate stopping rule requires every red-on-main check to have exactly one of fixed/retired/exempt." + +[[debt.should]] +component = ".github/workflows/mirror.yml" +issue = "Mirror to Git Forges is red on main at e1b6225 (run 36296845635). mirror-disroot, mirror-gitea, mirror-codeberg and mirror-bitbucket fail; mirror-gitlab, mirror-sourcehut and mirror-radicle are green. Looks like per-forge credential or host reachability rather than a workflow defect." +effort = "medium" +impact = "medium" +discovered = "2026-09-27" +note = "Also red at a94b5b5, so it predates the current branch. No determination row yet." + +[[debt.should]] +component = "repository settings (owner-side)" +issue = "The Branch-Floor ruleset (id 23869449, target ~DEFAULT_BRANCH) carries only 'deletion' and 'non_fast_forward'. It has no required_status_checks rule, so a red Lock Sync Gate or rust-core job is a convention rather than an enforcement." +effort = "easy" +impact = "high" +discovered = "2026-09-27" +note = "Owner action, listed in PR #73. Add 'actions.lock is in sync with the workflow YAML' and 'Rust core (tests, formatting, lint)', and tick 'require branches to be up to date'." + +[[debt.should]] +component = "rust/pdftool_core" +issue = "Ruled-line, per-character-cell and baseline detection are not implemented. detect_blocks reports widget annotation rectangles only. This is the 'hand spacing' case the project is named for, so it is the actual product gap rather than incidental debt." +effort = "hard" +impact = "high" +discovered = "2026-09-27" +note = "This is the thing to build next if the goal is the product rather than the plumbing." # ============================================================================ # COULD — would fix eventually # ============================================================================ -# These are low-priority items that don't justify a session on their own. -# They get picked up when an agent is in the area for other reasons. -# -# Example: -# [[debt.could]] -# component = "cicada" -# issue = "RSR_OUTLINE.adoc references banned AGPL-3.0" -# effort = "easy" -# impact = "low" -# discovered = "2026-03-23" + +[[debt.could]] +component = "deno.lock" +issue = "A ~90 KB deno.lock sits in the repository root, but #43 (2026-08-24) deleted deno.json and every deno task. It is an orphan and it is the single most likely thing to make a reviewer think this is a Deno project." +effort = "easy" +impact = "medium" +discovered = "2026-09-27" +note = "Deleting it is safe, but confirm with the owner first — it may be referenced by an estate tool outside this checkout." + +[[debt.could]] +component = "webpack.config.cjs" +issue = "A webpack config for a bundle pipeline that does not exist in this checkout (no package.json, no node_modules, no AffineScript compiler config). Reinforces the same wrong impression as deno.lock." +effort = "easy" +impact = "low" +discovered = "2026-09-27" + +[[debt.could]] +component = "Justfile" +issue = "The crg-grade and crg-badge recipes read READINESS.md, which does not exist. Both silently fall back to grade 'X'. The CRG grade actually lives in TEST-NEEDS.adoc." +effort = "easy" +impact = "low" +discovered = "2026-09-27" +note = "Also, the tour and llm-context recipes look for README.md before README.adoc." + +[[debt.could]] +component = "TEST-NEEDS.adoc" +issue = "States 'CI workflows | 15'. There are 14 workflow files in .github/workflows (the 15th file is actions.lock). The document header also still reads 'TEST-NEEDS.md'." +effort = "easy" +impact = "low" +discovered = "2026-09-27" + +[[debt.could]] +component = "repository topics" +issue = "Topics are automation, cli-tool, developer-tools, epistemic-computing, epistemic-infrastructure, equivalence-aware-computing, hyperpolymath, open-source, rust, typed-provenance, veridical-computing. None of them say pdf, firefox-extension, wasm, affinescript or document-suite, so the repo is not discoverable by what it actually is." +effort = "easy" +impact = "low" +discovered = "2026-09-27" +note = "Owner-side setting change; also update the GitHub description to match the boundary statement." + +[[debt.could]] +component = "CHANGELOG.adoc" +issue = "The [Unreleased] section was tidied into Keep-a-Changelog prose on 2026-09-27, but it is still derived from commit subjects by hand. The canonical git-cliff config is hyperpolymath/standards/templates/cliff.toml, and the changelog-reusable workflow it feeds has not been adopted here." +effort = "medium" +impact = "low" +discovered = "2026-09-27" + +[[debt.could]] +component = ".machine_readable/6a2/ECOSYSTEM.a2ml" +issue = "Says only 'type = component'. It could carry the suite counterparts now recorded in docs/ecosystem/ECOSYSTEM.adoc and INTENT.contractile, so machine readers get the boundary without parsing prose." +effort = "easy" +impact = "low" +discovered = "2026-09-27" diff --git a/.machine_readable/agent_instructions/methodology.a2ml b/.machine_readable/agent_instructions/methodology.a2ml index 754f357..c65d942 100644 --- a/.machine_readable/agent_instructions/methodology.a2ml +++ b/.machine_readable/agent_instructions/methodology.a2ml @@ -8,8 +8,8 @@ # Reference: ADR-002 in standards/agentic-a2ml/docs/ [metadata] -version = "1.0.0" -last-updated = "2026-03-24" +version = "1.1.0" +last-updated = "2026-09-27" spec = "https://github.com/hyperpolymath/standards/blob/main/agentic-a2ml/docs/ADR-002-methodology-layer.adoc" # ============================================================================ @@ -55,7 +55,7 @@ perfective = 10 # % for SPDX headers, doc updates, formatting, style # Customise this per project — the template default is generic. [methodology.unique-strength] -description = "{{PROJECT_UNIQUE_STRENGTH}}" +description = "Placement into fixed-layout forms that were designed for hand spacing: blocky-writer finds widget annotations in an existing PDF and writes values back into the AcroForm by field name, preserving page geometry exactly. Its nearest neighbours deliberately do not do this — Formatrix Docs views and edits, DocMatrix converts, Docudactyl extracts. Deepen the placement engine (ruled lines, per-character cells, baselines) rather than reaching into conversion or editing." deepen-not-broaden = true # ============================================================================ @@ -71,15 +71,16 @@ deepen-not-broaden = true [methodology.divergent-invariants] rules = [ - # Customise per project. Examples: - # "Idris2 only for formal verification — no Lean4, Coq, Agda", - # "believe_me count must remain zero", - # "FFI architecture: Idris2 → RefC → Zig → C ABI (no shortcuts)", + "Rust only for the core — do not introduce another language for PDF work", + "unsafe block count in rust/pdftool_core must remain zero (crate is #![forbid(unsafe_code)])", + "The WASM export surface stays at detect_blocks and fill_blocks unless a new contract is agreed", + "BW_* error codes are append-only; never rename or repurpose one", + "Never normalise page geometry to 'tidy' it — composition contract clause 4", + "No JavaScript or Deno toolchain — #43 removed it deliberately", ] # Optional: language invariant for the core strength -# If set, divergent mode will not introduce other languages for this purpose -# language-invariant = "idris2" +language-invariant = "rust" # ============================================================================ # CONSTRAINT HINTS @@ -89,9 +90,11 @@ rules = [ [methodology.known-constraints] constraints = [ - # Customise per project. Examples: - # "End-to-end build has never been verified", - # "libproject.so does not exist yet — all bindings call stubs", + "The AffineScript frontend cannot be built in this checkout — no compiler config, no package manifest, no bundle pipeline", + "deno.json and every deno task were deleted by #43 (2026-08-24); deno.lock is a leftover, not a declaration", + "Actions runs triggered by arena-ai-coding-agent[bot] are refused at startup, so bot-authored PRs show no checks at all", + "scripts/check-lock-sync.sh requires gawk, which is absent from most sandboxes", + "Branch-Floor ruleset carries no required_status_checks, so a red gate is a convention, not an enforcement", ] # ============================================================================ diff --git a/0-AI-MANIFEST.a2ml b/0-AI-MANIFEST.a2ml index 38f9fdc..67f63e1 100644 --- a/0-AI-MANIFEST.a2ml +++ b/0-AI-MANIFEST.a2ml @@ -1,6 +1,7 @@ ;; SPDX-License-Identifier: MPL-2.0 ;; 0-AI-MANIFEST.a2ml — AI Agent Entry Point ;; Repository: hyperpolymath/blocky-writer +;; Last reviewed: 2026-09-27 @abstract: AI manifest for blocky-writer. Read this file first before any other work. @@ -9,28 +10,73 @@ AI manifest for blocky-writer. Read this file first before any other work. ;; === CANONICAL LOCATIONS === ;; Machine-readable state: .machine_readable/ ;; Documentation: docs/ -;; Source code: src/ -;; Tests: verification/tests/ or tests/ +;; Source code: src/ (AffineScript prototype — not buildable here) +;; Implemented code: rust/pdftool_core/ (the only tested code in this repo) +;; Tests: tests/ and rust/pdftool_core/src/lib.rs (#[cfg(test)] mod tests) +;; Wiki source: wiki/ (published at github.com/hyperpolymath/blocky-writer/wiki) ;; === CRITICAL INVARIANTS === ;; - SPDX headers on ALL files (MPL-2.0) ;; - No believe_me, assert_total, sorry, Admitted, unsafeCoerce, Obj.magic +;; - rust/pdftool_core is #![forbid(unsafe_code)] — keep it that way ;; - SCM files ONLY in .machine_readable/ (never root) +;; - BW_* error codes are stable API; adding or renaming one is a breaking change +;; - Never silence a gate: no continue-on-error, no if: false, no quiet job deletion +;; - Any change to a workflow `uses:` line ships with the matching actions.lock +;; change in the SAME commit (verify with scripts/check-lock-sync.sh, needs gawk) ;; - Author: Jonathan D.A. Jewell +;; === READ IN THIS ORDER === +;; 1. README.adoc — what this is, current status, ecosystem boundary +;; 2. wiki/Home.md — same, longer, with a navigation table +;; 3. docs/ci/CHECK-DETERMINATIONS.adoc — the CI ledger AND its standing rules +;; 4. docs/ecosystem/ECOSYSTEM.adoc — what blocky-writer is NOT, and who does that +;; 5. rust/pdftool_core/src/lib.rs — the only implemented code +;; +;; Do NOT trust these without checking — each was corrected on 2026-09-27 and +;; may drift again: TOPOLOGY.adoc, .github/CONTRIBUTING.md, CHANGELOG.adoc, +;; EXPLAINME.adoc, .machine_readable/6a2/STATE.a2ml, www/.well-known/humans.txt, +;; docs/tech-debt-2026-05-26.adoc (a 2026-05 snapshot — see its status section), +;; and the Justfile's crg-grade/crg-badge recipes, which read a READINESS.md +;; that does not exist. + +;; === THE THREE THINGS THAT WILL SURPRISE YOU === +;; 1. The frontend is a PROTOTYPE. There is no AffineScript compiler config, no +;; JS package manifest and no bundle pipeline in this checkout. deno.json and +;; every `deno task` were deleted by #43 on 2026-08-24. The leftover +;; deno.lock is not a declaration of anything. Nothing is release-ready. +;; +;; 2. You probably cannot run the Rust checks. Most sandboxes have no Rust +;; toolchain and no crates.io access. If you cannot run cargo fmt/test/clippy, +;; say so explicitly in your PR. Do not imply you ran them. CI is the only +;; authority on green. +;; +;; 3. Actions runs triggered by arena-ai-coding-agent[bot] are REFUSED at startup +;; ("Actor is not allowed to trigger Actions workflows"). A bot-authored PR +;; therefore shows NO repository checks at all — not red, absent — because a +;; startup failure creates no check run. This is an org-side policy; no file +;; change cures it. The owner must trigger or merge. Do not add +;; continue-on-error, do not weaken a gate, and do not treat the absence of +;; checks as a pass. + +;; === WHAT TO DO FIRST === +;; If asked to "finish" something, check docs/ci/CHECK-DETERMINATIONS.adoc for an +;; open determination before writing code. Several items in this repo are +;; documented as deliberately outstanding rather than forgotten. + -## PRIORITY ACTION — this repository is not fully initialised +## Repository initialisation — COMPLETE + +All substitution tokens inherited from `hyperpolymath/rsr-template-repo` were +resolved on 2026-09-27. **Nothing is outstanding.** -10 substitution token(s) still have no value. **Read -`REQUIRES_INITIALISATION.md` in the repository root before doing anything -else here** — it lists every outstanding token, what it means, and which -files it belongs in. +The record of what was filled, and the evidence for each value, is in +`REQUIRES_INITIALISATION.adoc`. That file is safe to delete; it is retained only +until the estate top-up tool confirms and removes it. -Do not fabricate values for them, and do not delete the sections that -contain them to quiet a gate. They are unfilled because they need a -decision, not because they were overlooked. Resolve what you legitimately -can, leave the rest, and delete `REQUIRES_INITIALISATION.md` only when -nothing outstanding remains. +If you are an agent arriving after 2026-09-27 and this block still says +"not fully initialised", it is stale — treat the resolved state as authoritative +and fix the block. diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index ab27262..26a94c3 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -16,58 +16,96 @@ https://semver.org/spec/v2.0.0.html[Semantic Versioning]. === [Unreleased] +Entries below are grouped by Keep-a-Changelog section. Raw commit subjects are +not repeated verbatim — where a commit subject was mangled or carried an inline +`+Authored-By:+` trailer, it has been tidied here. + ==== Added -* feat(crg): add crg-grade and crg-badge justfile recipes -* feat: add wokelangiser accessibility+consent manifest -* feat: add UX Justfile with doctor, tour, help-me, assail recipes -* feat: add stapeln.toml layer-based container definitionfrom existing -Containerfile to stapeln format.Chainguard base, security hardening, -SBOM generation.-Authored-By: Claude Opus 4.6 (1M context) -noreply@anthropic.com -* feat: deploy UX Manifesto infrastructure -* feat: add CLADE.a2ml — clade taxonomy declaration -* feat: add mirror.yml workflow for GitLab/Bitbucket mirroring +* `+wiki/+` — BerryWiki-format wiki source (tree, backlinks, tags, zero + JavaScript) with `+_Sidebar.md+` generated from it, and `+wiki/README.adoc+` + documenting the format and the publish step. +* `+docs/ecosystem/ECOSYSTEM.adoc+` — the suite boundary statement required by + docmatrix#71, with the adjacent-project list and the composition contract. +* `+.github/ISSUE_TEMPLATE/+` — `+bug_report.yml+`, `+feature_request.yml+`, + `+documentation.yml+` and `+config.yml+`. There were previously no issue + templates at all, despite `+CONTRIBUTING.md+` referencing one. +* `+.github/PULL_REQUEST_TEMPLATE.md+` — including the "if you changed a `+uses:+` + line, ship the lock change" and "never silence a gate" checks. +* `+.machine_readable/6a2/STATE.a2ml+` — `+verified+`, `+not-implemented+`, + `+known-red-on-main+` and `+open-decisions+` sections, replacing a bare + `+completion-percentage+` that had been stale since 2026-03-15. +* UX Justfile recipes: `+doctor+`, `+tour+`, `+help-me+`, `+assail+`. +* CRG grade recipes: `+crg-grade+`, `+crg-badge+`. +* `+wokelangiser.toml+` accessibility and consent manifest. +* `+stapeln.toml+` — layer-based container definition converted from the existing + `+Containerfile+` (Chainguard base, security hardening, SBOM generation). +* `+CLADE.a2ml+` — clade taxonomy declaration, registered with `+gv-clade-index+`. +* `+mirror.yml+` — GitLab/Bitbucket (and Disroot, Gitea, Codeberg, SourceHut, + Radicle) mirroring. ==== Fixed -* fix(ci): resync actions.lock after #69/#70/#71 desync that startup-killed -every workflow on main; re-pin codeql-action to the held v4.38.0; correct the -dependabot codeql ignore glob; retire `core-fill-tests`/`extension-build` with -a written determination in docs/ci/CHECK-DETERMINATIONS.adoc (#67) -* fix(ci): sync hypatia-scan.yml to canonical (#5) -* fix(ci): adopt canonical hypatia-scan.yml (#4) -* fix(scorecard): enforce granular permissions and add fuzzing -placeholder -* fix(ci): Resolve workflow-linter self-matching and metadata issues -* fix: SPDX headers (AGPL→PMPL), email, author name -* fix(license): SPDX AGPL-3.0 → PMPL-1.0-or-later in dotfiles -* fix: security hardening and CI workflow pinning +* `+rust/pdftool_core+`: resolved the two Clippy lints that were the only thing + keeping the `+Rust core (tests, formatting, lint)+` job red — + `+clippy::map_clone+` on `+doc.get_object(*id).map(Clone::clone)+` (now + `+.cloned()+`) and `+clippy::unnecessary_cast+` on + `+Object::Real(v) => Some(*v as f32)+` (now `+Some(*v)+`). The adjacent + `+Object::Integer+` cast was left alone because that `+i64+` → `+f32+` cast is real. + (#73) +* `+rust/pdftool_core+`: `+rustfmt+` applied so the formatting step of the + `+rust-core+` job passes. (e1b6225) +* `+actions.lock+` resynchronised after the #69/#70/#71 desync that startup-killed + every workflow on `+main+`; `+codeql-action+` re-pinned to the held v4.38.0; the + Dependabot codeql ignore glob corrected to `+github/codeql-action*+`; the dead + `+core-fill-tests+` and `+extension-build+` jobs retired with a written + determination in `+docs/ci/CHECK-DETERMINATIONS.adoc+`. (#67) +* Documentation drift: `+.github/CONTRIBUTING.md+` rewritten (it described + `+hyperpolymath/language-bridges+` and a repo layout that does not exist here); + `+TOPOLOGY.adoc+` corrected (it claimed a Deno-first toolchain and 100% frontend + completion); `+EXPLAINME.adoc+` corrected (it listed Deno as a technology + choice); `+www/.well-known/humans.txt+` corrected (it described an Idris2/Zig + project); `+0-AI-MANIFEST.a2ml+` broken references fixed. +* `+docs/ci/CHECK-DETERMINATIONS.adoc+`: the `+rust-core+` row corrected — the job + *has* executed (run 36296845297 at `+e1b6225+`), reaching its third step with + `+fmt+` and `+test+` green and only Clippy red. The previous revision claimed it + had never run. +* `+hypatia-scan.yml+` synced to the canonical estate version. +* Scorecard: granular permissions enforced; fuzzing placeholder added. +* Workflow linter self-matching and metadata issues resolved. +* SPDX headers corrected (AGPL → PMPL) along with author name and email. ==== Changed -* refactor: migrate 6SCM → 6A2 (.scm → .a2ml format) +* `+.machine_readable/+` migrated from 6SCM to 6A2 (`+.scm+` → `+.a2ml+`). +* `+README.adoc+` gained an *Ecosystem position* section stating the boundary and + linking the other suite components, satisfying the first acceptance criterion + of docmatrix#71. +* CodeQL Action v3 → v4. ==== Documentation -* docs: add TEST-NEEDS.md (CRG C) -* docs: add TEST-NEEDS.md (CRG C) -* docs: restore README.md lost in Floor Raise campaign -* docs: add EXPLAINME.adoc — prove-it file backing README claims -* docs: add 0-AI-MANIFEST.a2ml (RSR compliance) +* `+TEST-NEEDS.adoc+` — CRG grade C. +* `+EXPLAINME.adoc+` — prove-it file backing README claims. +* `+0-AI-MANIFEST.a2ml+` — RSR compliance entry point. +* `+REQUIRES_INITIALISATION.adoc+` — rewritten as a resolution record; all + inherited substitution tokens are now filled. ==== CI -* ci: deploy dogfood-gate, fix hypatia-scan, add pre-commit hooks -* ci: migrate CodeQL Action v3 → v4 -* ci: update SHA pins for codeql-action and trufflehog -* ci: deploy missing standard workflows (10 added) +* `+lock-sync-gate.yml+` added as the authoritative `+actions.lock+` gate; the + duplicate in-workflow lock job removed from `+ci.yml+` because a workflow that + GitHub refuses to start when the lock is broken can never report the fault it + exists to catch. +* Dogfood gate deployed; pre-commit hooks added. +* SHA pins updated for `+codeql-action+` and `+trufflehog+`. +* Ten standard estate workflows deployed. === Pre-history -Prior commits to this file’s introduction are recorded in git history +Prior commits to this file's introduction are recorded in git history but not formally classified into Keep-a-Changelog sections. To backfill, -run `+git cliff -o CHANGELOG.md+` locally using the canonical +run `+git cliff -o CHANGELOG.adoc+` locally using the canonical https://github.com/hyperpolymath/standards/blob/main/templates/cliff.toml[`+cliff.toml+`] — this is one-shot mechanical work. diff --git a/EXPLAINME.adoc b/EXPLAINME.adoc index f018288..632b7c6 100644 --- a/EXPLAINME.adoc +++ b/EXPLAINME.adoc @@ -5,30 +5,63 @@ The README makes claims. This file backs them up. -[quote, README] -____ -See the link:README.adoc[README] for details. -____ - == Technology Choices [cols="1,2"] |=== | Technology | Learn More -| **Deno** | https://deno.land -| **AffineScript** | https://affinescript-lang.org +| **Rust** | https://www.rust-lang.org +| **lopdf** | https://crates.io/crates/lopdf — PDF object model, parsing, serialisation +| **wasm-bindgen** | https://rustwasm.github.io/wasm-bindgen — the export surface +| **AffineScript** | https://affinescript-lang.org — the frontend language (prototype; no toolchain here) |=== +NOTE: Deno is *not* used. `deno.json` and every `deno task` were removed in #43 +(2026-08-24). The `deno.lock` file still in the tree is a leftover, not a +declaration of anything. + == File Map [cols="1,2"] |=== | Path | What's There -| `src/` | Source code -| `lib/` | Library code -| `test(s)/` | Test suite +| `rust/pdftool_core/src/lib.rs` | The whole core: `detect_blocks`, `fill_blocks`, the field walkers, the `BW_*` error taxonomy, and 6 unit tests. ~1030 lines. +| `src/*.affine` | AffineScript prototype: popup, content script, background script, `core/PdfTool`, `core/Storage`, `core/ProvenMount`, `components/Block`, `components/FormFiller`. Not buildable in this checkout. +| `public/` | `manifest.json`, `popup.html`, icons. +| `tests/aspect/` | Aspect-oriented test shell script. +| `tests/fuzz/` | Placeholder only. +| `scripts/build-wasm.sh` | WASM package build. Not run by CI; output unconsumed. +| `scripts/check-lock-sync.sh` | The `actions.lock` gate (needs `gawk`). +| `wiki/` | BerryWiki-format wiki source. See `wiki/README.adoc`. +| `docs/ci/CHECK-DETERMINATIONS.adoc` | The CI ledger and its standing rules. +| `docs/ecosystem/ECOSYSTEM.adoc` | Suite boundary and adjacent projects. +| `.machine_readable/` | Machine-readable state, contractiles, clade declaration. +| `www/.well-known/` | `ai.txt`, `humans.txt`, `security.txt`. +|=== + +== Claims, and where they are checked + +[cols="1,2",options="header"] +|=== +| Claim in the README | Where it is checked + +| The Rust core is implemented and has unit tests +| `cargo test --manifest-path rust/pdftool_core/Cargo.toml --locked` — 6 tests, including AcroForm writeback for text/select and button widgets and the structured error taxonomy. + +| `cargo fmt`, `cargo test` and `cargo clippy -D warnings` all pass +| `.github/workflows/ci.yml`, job `Rust core (tests, formatting, lint)`. As of 2026-09-27 this job is green on `main` at `e1b6225`. + +| The frontend is a prototype with no build pipeline +| There is no AffineScript compiler configuration and no JavaScript package manifest in the tree. `deno.json` was deleted by #43. + +| `fill_blocks` performs AcroForm-aware writeback +| `apply_field_value` in `rust/pdftool_core/src/lib.rs`, dispatched on field type `Tx` / `Ch` / `Btn`. + +| Errors carry structured codes +| `CoreErrorPayload { code, message, context }`; 20 `BW_*` codes. + |=== == Questions? diff --git a/README.adoc b/README.adoc index 24c0719..0f6ce52 100644 --- a/README.adoc +++ b/README.adoc @@ -62,6 +62,30 @@ See TOPOLOGY for a visual architecture map and completion dashboard. Wondering how this works? See EXPLAINME.adoc. +== Ecosystem position + +blocky-writer is one component of the hyperpolymath *precision document suite*. +It owns exactly one thing: **fitting and placement into fixed-layout PDF and +application-form boxes, baselines and per-character cells designed for hand +spacing rather than reliable computer entry.** + +It deliberately does *not* do any of the following, and each has an owner: + +* Multi-format viewing and editing — https://github.com/hyperpolymath/formatrix-docs[Formatrix Docs] +* Multi-format conversion and precision coordination — https://github.com/hyperpolymath/docmatrix[DocMatrix] +* OCR / metadata extraction — https://github.com/hyperpolymath/docudactyl[Docudactyl] +* Print routing — https://github.com/hyperpolymath/presswerk[Presswerk] + +The versioned composition contract — including the clause that forbids any +component from silently normalising *page geometry* — is +https://github.com/hyperpolymath/docmatrix/issues/71[docmatrix#71]. The long-form +boundary statement, with the full adjacent-project list, is +`+docs/ecosystem/ECOSYSTEM.adoc+`. + +The project wiki (BerryWiki format) is at +https://github.com/hyperpolymath/blocky-writer/wiki and its source lives in +`+wiki/+`. + == License SPDX-License-Identifier: CC-BY-SA-4.0 + diff --git a/REQUIRES_INITIALISATION.adoc b/REQUIRES_INITIALISATION.adoc index d685768..f9a95da 100644 --- a/REQUIRES_INITIALISATION.adoc +++ b/REQUIRES_INITIALISATION.adoc @@ -1,131 +1,84 @@ -== REQUIRES INITIALISATION - -*This repository is not finished being set up.* 10 substitution token(s) -across 3 file(s) still have no value. - -=== Why this is not already done - -This repo was created from `+hyperpolymath/rsr-template-repo+`. The mint -(`+just repo-init+`) fills every token that has a single mechanical -answer — owner, repo, author, dates, licence, branch — and it has done -so here. - -The tokens below are the ones it _deliberately cannot_ answer. They need -a decision or a fact that exists only in your head: what this project is -for, what command builds it, which port the service listens on, whether -a PGP key is held at all. The template’s own token vocabulary says as -much — you cannot sensibly answer "`required invariants`" in a -thirty-second bootstrap. - -They were left *visibly unfilled on purpose*. The alternatives were both -worse: inventing plausible values would put confident falsehoods into a -security policy and an architecture document, and silently deleting the -sections would hide the fact that a decision is owed. A visible gap is -honest; a fabricated answer is not. - -=== Do not delete this file until every item below is resolved - -This file is the only marker that the work is outstanding. Deleting it -early does not finish the setup, it just conceals it — and the next -person or agent to arrive will reasonably assume the repo is complete. - -* *If you are a person:* delete this file yourself once the last item is -done. -* *If you are an agent:* resolve what you legitimately can, leave the -rest, and delete this file only when no token below remains anywhere in -the tree. Do not delete it to make a gate go green. - -Re-running the estate top-up tool will remove this file automatically -once nothing is outstanding, so the safest way to finish is to fix the -tokens and let the check confirm it. - -=== What is needed, and where it goes - -==== `+{{CONDUCT_TEAM}}+` - -Name of the conduct body. If there is no committee, rewrite the sentence -rather than substituting a plural noun into '`a \{\{CONDUCT_TEAM}} -member`'. - -Appears in: - -* `+CODE_OF_CONDUCT.md+` - -==== `+{{CONSUMER1}}+` - -A downstream repo that consumes this one. - -Appears in: - -* `+.machine_readable/INTENT.contractile+` - -==== `+{{CONSUMER2}}+` - -A second downstream consumer. - -Appears in: - -* `+.machine_readable/INTENT.contractile+` - -==== `+{{DEP1}}+` - -First named dependency, in .machine_readable/INTENT.contractile. - -Appears in: - -* `+.machine_readable/INTENT.contractile+` - -==== `+{{DEP2}}+` - -Second named dependency, in .machine_readable/INTENT.contractile. - -Appears in: - -* `+.machine_readable/INTENT.contractile+` - -==== `+{{MONOREPO_OR_STANDALONE}}+` - -Literally '`monorepo`' or '`standalone`'. - -Appears in: - -* `+.machine_readable/INTENT.contractile+` - -==== `+{{ONE_PARAGRAPH_ANTI_PURPOSE}}+` - -A paragraph on what this deliberately is NOT for. - -Appears in: - -* `+.machine_readable/INTENT.contractile+` - -==== `+{{ONE_PARAGRAPH_PURPOSE}}+` - -A paragraph on what this is for. - -Appears in: - -* `+.machine_readable/INTENT.contractile+` - -==== `+{{PROJECT_UNIQUE_STRENGTH}}+` - -What this does that its alternatives do not. - -Appears in: - -* `+.machine_readable/agent_instructions/methodology.a2ml+` - -==== `+{{RESPONSE_TIME}}+` - -Initial-response SLA for a security or conduct report. Promise only what -a solo maintainer can actually meet. - -Appears in: - -* `+CODE_OF_CONDUCT.md+` - -''''' - -Generated by the estate top-up pass. Rationale and the governing rulings -are in `+hyperpolymath/standards+`; the token vocabulary is -`+.machine_readable/ai/PLACEHOLDERS.adoc+` in `+rsr-template-repo+`. +== REQUIRES INITIALISATION — RESOLVED 2026-09-27 + +*All substitution tokens this repository inherited from +`+hyperpolymath/rsr-template-repo+` have been resolved. Nothing is outstanding. +This file is retained as the record of that, and is safe to delete.* + +== What was outstanding, and where it went + +A previous revision of this file listed *10 tokens across 3 files*. That count +was itself stale: two of the three (`+{{CONDUCT_TEAM}}+` and +`+{{RESPONSE_TIME}}+`, said to be in `+CODE_OF_CONDUCT.md+`) had already been +resolved — `+CODE_OF_CONDUCT.adoc+` contains no tokens at all, and the +initial-response SLA is documented in `+SECURITY.adoc+` (48 hours, see +`+#response-timeline+`). Eight tokens were live, in two files. All eight are now +filled. + +[cols="1,2,3",options="header"] +|=== +| Token | File | Value used, and why + +| `+{{ONE_PARAGRAPH_PURPOSE}}+` +| `.machine_readable/INTENT.contractile` +| Derived from `+README.adoc+` and `+docs/ecosystem/ECOSYSTEM.adoc+`: filling + fixed-layout PDF and application-form boxes, baselines and per-character cells + designed for hand spacing. + +| `+{{ONE_PARAGRAPH_ANTI_PURPOSE}}+` +| `.machine_readable/INTENT.contractile` +| Derived from the suite boundary in + https://github.com/hyperpolymath/docmatrix/issues/71[docmatrix#71]: not a + viewer/editor (Formatrix Docs), not a converter (DocMatrix), not OCR + (Docudactyl), not a print router (Presswerk), not a reconciler + (recon-silly-ation), not ForthWall. + +| `+{{MONOREPO_OR_STANDALONE}}+` +| `.machine_readable/INTENT.contractile` +| `+standalone+` — this repository is not a workspace root; it holds one crate + and one prototype frontend. + +| `+{{DEP1}}+` / `+{{DEP2}}+` +| `.machine_readable/INTENT.contractile` +| `+lopdf+` / `+wasm-bindgen+` — read directly from + `+rust/pdftool_core/Cargo.toml+`. + +| `+{{CONSUMER1}}+` / `+{{CONSUMER2}}+` +| `.machine_readable/INTENT.contractile` +| `+docmatrix+` / `+formatrix-docs+` — the two suite projects that + https://github.com/hyperpolymath/docmatrix/issues/71[docmatrix#71] names + alongside blocky-writer. An explicit note in the file records that these are + boundary counterparts, not code-level consumers: no repository depends on + this one in either direction. + +| `+{{PROJECT_UNIQUE_STRENGTH}}+` +| `.machine_readable/agent_instructions/methodology.a2ml` +| Placement into fixed-layout forms — the one thing the nearest neighbours + deliberately do not do. + +|=== + +== Also filled while here + +The template's `+*REMINDER:+` placeholders in the same two files were empty +comments. They are now filled with values derived from this repository: + +* `+INTENT.contractile+` `+architectural-invariants+` — six load-bearing + decisions, including the two-function WASM boundary, name-driven (not + coordinate-driven) writeback, append-only `+BW_*+` codes, and the clause-4 + prohibition on normalising page geometry. +* `+INTENT.contractile+` `+ask-before-touching+` — five sensitive areas. +* `+methodology.a2ml+` `+divergent-invariants.rules+` and + `+known-constraints.constraints+`. + +== Nothing was invented + +Every value above is traceable to a file in this repository or to docmatrix#71. +Where a value would have required a judgement nobody has recorded — the two +conduct tokens — they turned out to be already resolved elsewhere, and that is +noted rather than papered over. + +== Deleting this file + +Safe to delete. The estate top-up tool removes it automatically once it finds +nothing outstanding; until that pass runs, it is kept as the marker that the +work was done deliberately rather than by deleting the sections. diff --git a/TEST-NEEDS.adoc b/TEST-NEEDS.adoc index a6e05b9..761b2a3 100644 --- a/TEST-NEEDS.adoc +++ b/TEST-NEEDS.adoc @@ -1,30 +1,43 @@ -== TEST-NEEDS.md — blocky-writer +// SPDX-License-Identifier: MPL-2.0 +== TEST-NEEDS.adoc — blocky-writer === CRG Grade: C — ACHIEVED 2026-04-04 +Last reviewed: 2026-09-27. + === Current Test State [cols=",,",options="header",] |=== |Category |Count |Notes |Test directories |1 |Location(s): /tests (aspect + fuzz placeholder) -|CI workflows |15 |`ci.yml` runs the Rust core checks; see docs/ci/CHECK-DETERMINATIONS.adoc -|Unit tests |Implemented |Rust `pdftool_core` (`cargo test --locked`) +|CI workflows |14 |`.github/workflows/*.yml`. `ci.yml` runs the Rust core checks; `actions.lock` is a file, not a workflow. See docs/ci/CHECK-DETERMINATIONS.adoc +|Unit tests |6 |Rust `pdftool_core` — `cargo test --manifest-path rust/pdftool_core/Cargo.toml --locked` |=== -=== What’s Covered +=== What's Covered -* [x] Rust core unit tests (block detection, `fill_blocks_*` AcroForm writeback, taxonomy errors) -* [x] `cargo fmt --check` and `cargo clippy -D warnings` in CI +* [x] Rust core unit tests (block detection, `fill_blocks_*` AcroForm writeback for + `Tx`/`Ch`/`Btn` fields, taxonomy errors) — 6 tests, all green on `main` at `e1b6225` +* [x] `cargo fmt -- --check` in CI — green +* [x] `cargo clippy --all-targets -- -D warnings` in CI — green (the two remaining + lints were fixed in #73) +* [x] `actions.lock` synchronisation gate (`lock-sync-gate.yml`) — green on `main` === Still Missing (for CRG B+) * [ ] Extension frontend build + tests — no AffineScript/bundle toolchain in this checkout (retired CI job `extension-build`; see docs/ci/CHECK-DETERMINATIONS.adoc) * [ ] Code coverage reports (codecov integration) -* [ ] Detailed test documentation in CONTRIBUTING.md -* [ ] Integration tests beyond unit tests +* [ ] Detailed test documentation in `.github/CONTRIBUTING.md` — the file now exists and + documents how to run the core checks, but there is no test-authoring guide +* [ ] Integration tests beyond unit tests — in particular, no test loads a real-world + AcroForm PDF from disk; the fixture is synthesised in `mod tests` +* [ ] Property tests for the field walkers (`collect_field_ids`, `field_full_name`, + `field_type`) — these recurse and are cycle-guarded, which is exactly the shape + property tests pay off on * [ ] Performance benchmarking suite +* [ ] Ruled-line, per-character-cell and baseline detection — unimplemented, so untestable === Run Tests @@ -34,3 +47,6 @@ cargo fmt --manifest-path rust/pdftool_core/Cargo.toml -- --check cargo test --manifest-path rust/pdftool_core/Cargo.toml --locked cargo clippy --manifest-path rust/pdftool_core/Cargo.toml --locked --all-targets -- -D warnings ---- + +If you cannot run these — no Rust toolchain, no crates.io access — say so in the +PR rather than implying you did. CI is the only authority on green. diff --git a/TOPOLOGY.adoc b/TOPOLOGY.adoc index 412decc..beb35f1 100644 --- a/TOPOLOGY.adoc +++ b/TOPOLOGY.adoc @@ -1,5 +1,10 @@ == blocky-writer — Project Topology +.... +Last updated: 2026-09-27 +Status: Rust core green (fmt + 6 tests + clippy); frontend prototype, no build pipeline +.... + === System Architecture .... @@ -11,7 +16,7 @@ ▼ ┌─────────────────────────────────────────┐ │ EXTENSION UI LAYER │ - │ (AffineScript + React + Office.js) │ + │ (AffineScript — prototype) │ │ ┌───────────┐ ┌───────────────────┐ │ │ │ Popup UI │ │ Content Script │ │ │ └─────┬─────┘ └────────┬──────────┘ │ @@ -20,7 +25,7 @@ ▼ ▼ ┌─────────────────────────────────────────┐ │ BACKGROUND SERVICE │ - │ (AffineScript, State Management) │ + │ (AffineScript — prototype) │ └───────────────────┬─────────────────────┘ │ ▼ @@ -37,34 +42,43 @@ ┌─────────────────────────────────────────┐ │ REPO INFRASTRUCTURE │ - │ Deno-first scripts .machine_readable/ │ - │ webpack.config.cjs Containerfile │ + │ .machine_readable/ Containerfile │ + │ .github/workflows/ wiki/ │ └─────────────────────────────────────────┘ .... === Completion Dashboard +Read this as *what exists and is verified*, not as *what is written down*. +The AffineScript layers are prototypes: the sources exist, but there is no +compiler configuration, no package manifest and no bundle pipeline in this +checkout, so there is nothing to build, run or release. Percentages below +reflect working, verified code — not the presence of files. + .... COMPONENT STATUS NOTES ───────────────────────────────── ────────────────── ───────────────────────────────── EXTENSION LAYERS - Popup UI (AffineScript/React) ██████████ 100% Stateful forms stable - Background Script ██████████ 100% WASM bridge active - Content Script ████████░░ 80% PDF block detection refining + Popup UI (AffineScript) ██░░░░░░░░ 20% src/popup.affine prototype; no build + Background Script ██░░░░░░░░ 20% src/background.affine prototype + Content Script █░░░░░░░░░ 10% src/content.affine prototype + Extension bundle pipeline ░░░░░░░░░░ 0% deno.json removed in #43; no toolchain CORE (RUST/WASM) - pdftool_core (WASM) ██████████ 100% Core logic stable - AcroForm Writeback ██████████ 100% Text/Select widgets verified - Error Taxonomy ██████████ 100% Structured error codes active + pdftool_core (WASM) ████████░░ 80% detect_blocks + fill_blocks, 6 tests green + AcroForm Writeback ████████░░ 80% Tx / Ch / Btn only; no Sig + Ruled-line & cell detection ░░░░░░░░░░ 0% NOT IMPLEMENTED — the "hand spacing" case + Error Taxonomy ██████████ 100% 20 stable BW_* codes REPO INFRASTRUCTURE - Rust CI (fmt/test/clippy) ██████████ 100% ci.yml rust-core job - Extension bundle pipeline ░░░░░░░░░░ 0% deno.json removed in #43; no toolchain + Rust CI (fmt/test/clippy) ██████████ 100% ci.yml rust-core job — green + Lock Sync Gate ██████████ 100% lock-sync-gate.yml — green on main + Documentation ████████░░ 80% README/TOPOLOGY/wiki corrected 2026-09-27 .machine_readable/ ██████████ 100% STATE.a2ml tracking Containerfile ██████████ 100% Reproducible dev env ───────────────────────────────────────────────────────────────────────────── -OVERALL: █████████░ ~90% Production-ready extension +OVERALL: █████░░░░░ ~50% Rust core ready; extension not release-ready .... === Key Dependencies @@ -72,8 +86,17 @@ OVERALL: █████████░ ~90% Produ .... Block Detection ───► AcroForm Parser ───► WASM Bridge ───► Extension UI (Rust) (Rust) (JS) (AffineScript) + +lopdf 0.34 ─────────► rust/pdftool_core ─────────► detect_blocks / fill_blocks .... +=== Ecosystem + +See `+docs/ecosystem/ECOSYSTEM.adoc+` for the boundary statement and the +adjacent-project list, and +https://github.com/hyperpolymath/docmatrix/issues/71[docmatrix#71] for the +versioned composition contract. + === Update Protocol This file is maintained by both humans and AI agents. When updating: @@ -86,3 +109,8 @@ This file is maintained by both humans and AI agents. When updating: Progress bars use: `+█+` (filled) and `+░+` (empty), 10 characters wide. Percentages: 0%, 10%, 20%, … 100% (in 10% increments). + +*Rule of honesty:* a bar describes **working, verified code**. A file that +exists but cannot be compiled, run or tested is 0%, however large it is. The +`+deno.json+` deletion in #43 (2026-08-24) is why the extension layers are low +despite having sources. diff --git a/docs/ci/CHECK-DETERMINATIONS.adoc b/docs/ci/CHECK-DETERMINATIONS.adoc index ff9fe57..ca3fee7 100644 --- a/docs/ci/CHECK-DETERMINATIONS.adoc +++ b/docs/ci/CHECK-DETERMINATIONS.adoc @@ -37,16 +37,26 @@ muting it (`continue-on-error`, demotion to a warning, or silent removal). gone until the thing it would build exists. | `rust-core` (CI) -| *Fixed -- verification pending an owner-actor run* +| *Fixed -- awaiting one owner-triggered green run on `main`* | 2026-09-27 -| Replacement for both retired jobs: `cargo fmt --check`, `cargo test - --locked`, `cargo clippy -D warnings` on `rust/pdftool_core`. It has never - once executed: every `ci.yml` run before #71 died on the Deno tasks, #71's - own PR and merge were bot-triggered and refused at startup (<>), and - the fix PR for #67 is bot-triggered too. The first run that can execute it - is one triggered by `hyperpolymath` (re-run, close/reopen, or push). If that - run is red, the crate has a real defect and this row becomes a repair item; - it is not closed until a green run on `main` exists. +| Replacement for both retired jobs: `cargo fmt -- --check`, `cargo test + --locked`, `cargo clippy --all-targets -- -D warnings` on + `rust/pdftool_core`. It did execute once, contrary to the previous revision + of this row: run 36296845297 (push, `e1b6225`, actor `hyperpolymath`) got as + far as three of its steps -- *Check formatting* `success`, *Run unit tests* + `success` (6/6), *Run Clippy* `failure`. Clippy was the only red step and it + reported exactly two lints, both in `rust/pdftool_core/src/lib.rs`: + `clippy::map_clone` on `doc.get_object(*id).map(Clone::clone)` and + `clippy::unnecessary_cast` on `Object::Real(v) => Some(*v as f32)`. Both are + repaired in #73 (`.cloned()` and `Some(*v)` respectively); neither repair + weakens the gate, and the adjacent `Object::Integer(v) => Some(*v as f32)` + is deliberately left alone because that `i64` -> `f32` cast is real. The job + has *not* run with the repair in it: every run on #73's branch is + bot-triggered and refused at startup (<>), so the step is verified by + inspection only. This row therefore stays open until one run triggered by + `hyperpolymath` is green on `main`; if that run is red, the crate has a real + defect and this row becomes a repair item. It is not closed until such a run + exists. | `Lock Sync Gate` / `actions.lock is in sync with the workflow YAML` | *Fixed* diff --git a/docs/ecosystem/ECOSYSTEM.adoc b/docs/ecosystem/ECOSYSTEM.adoc new file mode 100644 index 0000000..734247a --- /dev/null +++ b/docs/ecosystem/ECOSYSTEM.adoc @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: MPL-2.0 += Ecosystem position — blocky-writer +:toc: +:toc-placement: preamble +:icons: font + +This file exists because of an acceptance criterion in +https://github.com/hyperpolymath/docmatrix/issues/71[docmatrix#71]: + +[quote] +____ +Each repository README and GitHub description states its own boundary and links +to the other optional components. +____ + +It is the long-form version of the boundary statement in the README. The +authoritative, versioned contract is docmatrix#71 itself — if the two disagree, +docmatrix#71 wins and this file is the thing that is stale. + +== What blocky-writer is + +A Mozilla Firefox extension for fitting and placing content into +**fixed-layout PDF and application-form boxes, baselines and per-character +cells** — the kind that were designed for hand spacing rather than reliable +computer entry. + +Concretely, today: an AcroForm field walker and writeback engine in Rust +(`rust/pdftool_core`), compiled to WASM, with two exported functions +(`detect_blocks`, `fill_blocks`) and a structured `BW_*` error taxonomy. + +== What blocky-writer is not + +* *Not a document viewer or editor.* Tabbed multi-format viewing and editing is + https://github.com/hyperpolymath/formatrix-docs[Formatrix Docs]. +* *Not a conversion engine.* Multi-format conversion and precision + coordination is https://github.com/hyperpolymath/docmatrix[DocMatrix]. +* *Not an OCR or extraction pipeline.* That is + https://github.com/hyperpolymath/docudactyl[Docudactyl]. +* *Not a print router.* That is https://github.com/hyperpolymath/presswerk[Presswerk]. +* *Not a cross-document consistency reconciler.* That is + https://github.com/hyperpolymath/recon-silly-ation[recon-silly-ation]. +* *Not a general PDF library.* It fills forms; it does not render, typeset or + lay out pages. +* *Not ForthWall.* ForthWall is a proposed, unbuilt, capability-bounded + execution layer. It is never a mandatory end-user product. + +== The suite + +[cols="1,2,2",options="header"] +|=== +| Project | Owns | Repo + +| blocky-writer +| Fixed-layout PDF and application-form placement +| https://github.com/hyperpolymath/blocky-writer[this repo] + +| DocMatrix +| Multi-format conversion and precision coordination for the suite +| https://github.com/hyperpolymath/docmatrix[hyperpolymath/docmatrix] + +| Formatrix Docs +| Tabbed viewing/editing of one logical document across TXT, tabular text, + Markdown, AsciiDoc, Djot, DEED, Org, reStructuredText and Typst +| https://github.com/hyperpolymath/formatrix-docs[hyperpolymath/formatrix-docs] + +| ForthWall +| Optional capability-bounded execution layer for critical operations + (_proposed, not implemented_) +| — + +|=== + +== Adjacent, not in the suite + +These are separate projects with their own boundaries. They are listed because +blocky-writer plausibly touches them, not because anyone has agreed a contract. + +[cols="1,2,2",options="header"] +|=== +| Project | Why it is adjacent | Repo + +| AffineScript +| The language `src/*.affine` targets. blocky-writer is a real consumer. +| https://github.com/hyperpolymath/affinescript[hyperpolymath/affinescript] + +| Docudactyl +| OCR, NER and metadata extraction — a plausible future source of field labels. +| https://github.com/hyperpolymath/docudactyl[hyperpolymath/docudactyl] + +| dotmatrix-fileprinter +| Sibling in the "matrix" naming line; filesystem-side manipulation. +| https://github.com/hyperpolymath/dotmatrix-fileprinter[hyperpolymath/dotmatrix-fileprinter] + +| Presswerk +| High-assurance local print routing; downstream of a filled PDF. +| https://github.com/hyperpolymath/presswerk[hyperpolymath/presswerk] + +| recon-silly-ation +| Cross-document consistency reconciler. Distinct from ForthWall. +| https://github.com/hyperpolymath/recon-silly-ation[hyperpolymath/recon-silly-ation] + +| universal-language-server-plugin +| Universal document conversion across editors; overlaps DocMatrix's remit. +| https://github.com/hyperpolymath/universal-language-server-plugin[hyperpolymath/universal-language-server-plugin] + +| gv-clade-index +| Taxonomy registry. `.machine_readable/CLADE.a2ml` registers this repo there. +| https://github.com/hyperpolymath/gv-clade-index[hyperpolymath/gv-clade-index] + +| deed-ecosystem / standards +| Governance and the `.deed` manifest format. +| https://github.com/hyperpolymath/deed-ecosystem[deed-ecosystem] / + https://github.com/hyperpolymath/standards[standards] + +| ddraig-ssg / casket-ssg +| The two SSGs behind the Pages workflows (see the conflict noted in + link:../ci/CHECK-DETERMINATIONS.adoc[the CI ledger]). +| https://github.com/hyperpolymath/ddraig-ssg[ddraig-ssg] / + https://github.com/hyperpolymath/casket-ssg[casket-ssg] + +| BerryWiki +| The format and tooling used by this project's wiki. +| https://github.com/metadatastician/berrywiki[metadatastician/berrywiki] + +|=== + +== The composition contract (summary) + +From docmatrix#71. blocky-writer is a party to all eight clauses, but clause 4 +is the one it is most likely to break: + +[quote] +____ +No component silently normalises punctuation, Unicode/whitespace, attribution, +terminology, document structure, or page geometry. +____ + +Page geometry is this project's entire subject. Normalising a rectangle "to be +helpful" is precisely the failure the contract forbids. + +== Proof obligations do not transfer + +* Conversion round-trip tests do not prove synchronised editor state. +* Editor tests do not prove fixed-layout PDF geometry. +* Exact page coordinates do not prove semantic correctness. +* Deterministic Forth execution does not prove the chosen operation or location + was correct. + +A green badge on a neighbour is not evidence about this repository, and this +repository's green `cargo test` is not evidence about a neighbour's. + +== How cross-repo communication works here + +There is no standing integration programme and none is planned. The working +pattern is deliberately light: + +. Each repo states its own boundary in its README and links the others. +. When a repo's status changes in a way that unblocks or affects a neighbour, + it files a short issue on that neighbour saying what changed and what the + neighbour can now progress with or consume. +. The neighbour decides whether to act. Nothing is merged across repos. + +If you are about to build something that belongs to a project in the table +above, stop and check that project's README and open issues first. diff --git a/docs/tech-debt-2026-05-26.adoc b/docs/tech-debt-2026-05-26.adoc index cee2985..46a08b8 100644 --- a/docs/tech-debt-2026-05-26.adoc +++ b/docs/tech-debt-2026-05-26.adoc @@ -1,5 +1,36 @@ == Tech-Debt Audit — blocky-writer — 2026-05-26 +''''' + +IMPORTANT: The sections below are a *snapshot taken on 2026-05-26*. Several +findings have since been resolved and some numbers are now wrong. Read +<> before acting on anything here. + +[[status-2026-09-27]] +== Status as of 2026-09-27 + +[cols="2,1,3",options="header"] +|=== +| Finding | Now | Evidence + +| `CHANGELOG.md` missing | *Resolved* | `CHANGELOG.adoc` exists and has an `[Unreleased]` section. It is still generated from commit subjects rather than maintained by hand, so the *quality* finding stands even though the *existence* finding does not. +| `CONTRIBUTING.md` present but wrong | *Resolved* | `.github/CONTRIBUTING.md` was rewritten on 2026-09-27. It had described `hyperpolymath/language-bridges`, a `lib/`/`extensions/`/`plugins/` layout, `just check`, `mix compile` and `flake.guix` — none of which exist here. +| No `docs/` directory | *Resolved* | `docs/` now holds `ci/CHECK-DETERMINATIONS.adoc`, `ecosystem/ECOSYSTEM.adoc`, `accessibility/`, `compliance/`, `reports/audit/` and the tech-debt files. +| `docs/` LoC 490, README 87 lines | *Stale numbers* | Both have grown. Recount rather than trusting these figures. +| README doing the work of `docs/` | *Partly resolved* | README is still the entry point, but `docs/ecosystem/ECOSYSTEM.adoc`, `TOPOLOGY.adoc`, `EXPLAINME.adoc` and `wiki/` now carry the detail. +| Documentation debt overall | *Reduced, not closed* | `TOPOLOGY.adoc` claimed a Deno-first toolchain and 100% frontend completion; `EXPLAINME.adoc` listed Deno as a technology choice; `www/.well-known/humans.txt` described an Idris2/Zig project. All three corrected on 2026-09-27. +| Proof debt (no `*.v`/`*.lean`/…) | *Unchanged* | Still none. See section 1 below. +| Licence debt | *Unchanged, still ok* | See section 2 below. + +|=== + +New debt introduced or discovered since the snapshot is recorded in +`.machine_readable/agent_instructions/debt.a2ml` and in the +`known-red-on-main` and `open-decisions` sections of +`.machine_readable/6a2/STATE.a2ml`. + +''''' + *Source:* estate-wide automated scan 2026-05-26. *Companion:* https://github.com/hyperpolymath/standards/tree/main/docs/audits[`+hyperpolymath/standards+` 2026-05-26-estate-*-debt audits]. *Combined severity:* `+MEDIUM+`. diff --git a/rust/pdftool_core/src/lib.rs b/rust/pdftool_core/src/lib.rs index 4ed0ee2..c6ceba9 100644 --- a/rust/pdftool_core/src/lib.rs +++ b/rust/pdftool_core/src/lib.rs @@ -48,7 +48,7 @@ fn core_error_to_js(payload: CoreErrorPayload) -> JsValue { fn resolve_object(doc: &Document, obj: &Object) -> Result { match obj { - Object::Reference(id) => doc.get_object(*id).map(Clone::clone), + Object::Reference(id) => doc.get_object(*id).cloned(), _ => Ok(obj.clone()), } } @@ -56,7 +56,7 @@ fn resolve_object(doc: &Document, obj: &Object) -> Result fn object_to_number(obj: &Object) -> Option { match obj { Object::Integer(v) => Some(*v as f32), - Object::Real(v) => Some(*v as f32), + Object::Real(v) => Some(*v), _ => None, } } diff --git a/wiki/Architecture.md b/wiki/Architecture.md new file mode 100644 index 0000000..a59ad17 --- /dev/null +++ b/wiki/Architecture.md @@ -0,0 +1,91 @@ + + + + +# Architecture + +## Layers + +``` +┌──────────────────────────────────────────────┐ +│ USER / BROWSER (Firefox, PDF forms) │ +└───────────────────────┬──────────────────────┘ + ▼ +┌──────────────────────────────────────────────┐ +│ EXTENSION UI LAYER │ +│ popup.affine content.affine │ +│ components/Block.affine components/FormFiller.affine +└───────────────────────┬──────────────────────┘ + ▼ +┌──────────────────────────────────────────────┐ +│ BACKGROUND SERVICE │ +│ background.affine core/Storage.affine │ +│ core/ProvenMount.affine │ +└───────────────────────┬──────────────────────┘ + ▼ +┌──────────────────────────────────────────────┐ +│ CORE PROCESSING (Rust → WASM) │ +│ rust/pdftool_core │ +│ detect_blocks() fill_blocks() │ +└───────────────────────┬──────────────────────┘ + ▼ +┌──────────────────────────────────────────────┐ +│ DATA LAYER │ +│ IndexedDB / local storage │ +└──────────────────────────────────────────────┘ +``` + +## What actually exists + +| Layer | Reality | +| --- | --- | +| Rust/WASM core | **Implemented and tested.** `rust/pdftool_core/src/lib.rs`, ~1030 lines, 6 unit tests. | +| AffineScript surfaces | **Prototype.** `src/*.affine` sources exist; no compiler config, no bundle pipeline. | +| Extension packaging | **Absent.** `public/manifest.json` and icons are present; nothing produces a loadable `.xpi`. | +| Storage | **Prototype.** `src/core/Storage.affine` only. | + +## The seam that matters + +Everything the extension does to a PDF goes through exactly two exported +functions. That boundary is the whole contract: + +```rust +#[wasm_bindgen] pub fn detect_blocks(pdf_data: &[u8]) -> Result +#[wasm_bindgen] pub fn fill_blocks(pdf_data: &[u8], blocks: JsValue, fields: JsValue) + -> Result +``` + +* `detect_blocks` walks every page's `Annots`, keeps the ones that are widget + annotations with a usable `Rect`, and returns a `Block { label, x, y, width, + height }` per widget. Labels come from the field's `/T`, falling back to the + parent field's `/T`, falling back to `field__`. +* `fill_blocks` takes the original PDF bytes plus a `field name → value` map, + writes the values into the AcroForm, and returns new PDF bytes. It is + **name-driven, not coordinate-driven** — the `blocks` argument is parsed and + validated but the writeback is keyed on field names. + +That last point is worth internalising: blocky-writer's contribution to the +document suite is *placement into fixed-layout forms*, not free-form layout. +See [Ecosystem](Ecosystem). + +## Error taxonomy + +Failures never cross the WASM boundary as strings. They are structured payloads +with a stable machine code, a human message, and optional context: + +```json +{ "code": "BW_FILL_NO_MATCHING_FIELDS", "message": "…", "context": "Choice" } +``` + +There are 20 `BW_*` codes. Codes are stable API — treat adding or renaming one +as a breaking change, not a tidy-up. diff --git a/wiki/CI-and-Gates.md b/wiki/CI-and-Gates.md new file mode 100644 index 0000000..08f599c --- /dev/null +++ b/wiki/CI-and-Gates.md @@ -0,0 +1,89 @@ + + + + +# CI and Gates + +Start here before you touch a workflow, a pin, or anything under `.github/`. + +## The gate that actually matters + +`.github/workflows/lock-sync-gate.yml` — **`actions.lock is in sync with the +workflow YAML`**. It carries no `uses:` of its own, so it is immune to the +failure it detects. + +GitHub refuses to *start* any workflow whose step-level `uses:` refs are not +recorded, under that workflow's own path, in `.github/workflows/actions.lock`. +The refusal is silent: `startup_failure`, zero jobs, no log. A stale lock entry +is as fatal as a missing one. + +**Rule: any change to a `uses:` line ships with the matching `actions.lock` +change in the same commit.** Verify with: + +```bash +scripts/check-lock-sync.sh # needs gawk +``` + +## The Rust gate + +`.github/workflows/ci.yml`, job **`Rust core (tests, formatting, lint)`** — the +only job in that workflow: + +| Step | Command | +| --- | --- | +| Check formatting | `cargo fmt --manifest-path rust/pdftool_core/Cargo.toml -- --check` | +| Run unit tests | `cargo test --manifest-path rust/pdftool_core/Cargo.toml --locked` | +| Run Clippy | `cargo clippy --manifest-path rust/pdftool_core/Cargo.toml --locked --all-targets -- -D warnings` | + +## Other workflows + +| Workflow | Purpose | +| --- | --- | +| `lock-sync-gate.yml` | The lockfile gate above. | +| `ci.yml` | The Rust core job. Deliberately contains **no** lockfile job — a lockfile checker inside a workflow that cannot start when the lock is broken can never report. | +| `codeql.yml` | CodeQL Advanced. | +| `governance.yml` | Governance checks. | +| `secret-scanner.yml` | Secret scanning. | +| `hypatia-scan.yml` | Neurosymbolic governance scan. | +| `mirror.yml` | Mirrors to GitLab, Bitbucket, Disroot, Gitea, Codeberg, SourceHut, Radicle. | +| `pages.yml` | Builds the Pages site with **Ddraig** (Idris 2). | +| `casket-pages.yml` | Builds the Pages site with **casket-ssg** (Haskell). | +| `boj-build.yml`, `instant-sync.yml`, `push-email-notify.yml`, `label-triage.yml`, `labels.yml` | Estate plumbing. | + +## Known problems — read before you trust a green + +* **Two Pages workflows.** `pages.yml` and `casket-pages.yml` both build and + deploy to the `github-pages` environment under the same `pages` concurrency + group, so they cancel each other. `pages.yml` also looks for `README.md`, + which does not exist here (this repo uses `README.adoc`), so it would publish + a bare `# hyperpolymath/blocky-writer` index. `casket-pages.yml` handles + `README.adoc` correctly. **Which one is canonical is undecided.** +* **The bot cannot trigger Actions.** Every run whose actor is + `arena-ai-coding-agent[bot]` is refused at startup with + `Actor is not allowed to trigger Actions workflows`. A bot-authored PR shows + *no* repository checks at all — not red, absent — because a startup failure + creates no check run. This is an org-side policy, not something a file change + can cure. Consequence: **the owner must trigger or merge**, and a bot merge + leaves `main` looking red even when the files are correct. +* **`Branch-Floor` has no `required_status_checks` rule.** So "removed from the + required set" is vacuously satisfied, and a red gate is a convention rather + an enforcement. The permanent cure is owner-side. + +## Where the determinations live + +`docs/ci/CHECK-DETERMINATIONS.adoc` is the ledger. Every CI check that has ever +been red on `main` has exactly one determination — *fixed*, *retired* or +*exempt* — and none is ever closed by muting it (`continue-on-error`, demotion +to a warning, or silent removal). Read the standing rules at the bottom before +you diagnose anything. diff --git a/wiki/Contributing--Dev-Setup.md b/wiki/Contributing--Dev-Setup.md new file mode 100644 index 0000000..3ca9620 --- /dev/null +++ b/wiki/Contributing--Dev-Setup.md @@ -0,0 +1,81 @@ + + + + +# Dev Setup + +## What you actually need + +For the Rust core — the only thing with tests — you need: + +* Rust stable with `rustfmt` and `clippy` components +* Network access to crates.io (or a vendored registry) + +```bash +rustup toolchain install stable --component rustfmt clippy +``` + +That is it. There is no Node, Deno, npm or wasm-pack requirement for the core +checks, despite what older documents in this repo may say. + +## What you do **not** need, and cannot currently use + +* **Deno** — `deno.json` was removed in #43 (2026-08-24) along with every + `deno task`. The `deno.lock` file still in the tree is a leftover. +* **wasm-pack** — only needed for `scripts/build-wasm.sh`, which produces a WASM + package nothing in this repo currently consumes. +* **An AffineScript toolchain** — `src/*.affine` cannot be compiled here. There + is no compiler configuration in this checkout. + +If a document tells you to run `just check`, `mix compile`, or `guix develop`, +it is describing a different repository. See +[Contributing](Contributing) for what is real. + +## First run + +```bash +git clone https://github.com/hyperpolymath/blocky-writer.git +cd blocky-writer + +cargo fmt --manifest-path rust/pdftool_core/Cargo.toml -- --check +cargo test --manifest-path rust/pdftool_core/Cargo.toml --locked +cargo clippy --manifest-path rust/pdftool_core/Cargo.toml --locked --all-targets -- -D warnings +``` + +`cargo test` runs 6 tests. If you get a different number, something changed and +the wiki is stale — fix the wiki. + +## Building the WASM package (optional) + +```bash +scripts/build-wasm.sh +``` + +Requires `wasm-pack` and the `wasm32-unknown-unknown` target. Nothing in CI does +this, and nothing consumes the output yet. + +## Tooling files in the tree, and what they are for + +| File | Status | +| --- | --- | +| `Justfile`, `contractile.just` | Task runner recipes. | +| `mise.toml`, `.tool-versions` | Tool version pinning. | +| `stapeln.toml` | Layer-based container definition. | +| `Containerfile` | Container build. | +| `selur-compose/compose.toml` | Compose definition. | +| `.editorconfig`, `.gitattributes` | Editor and git hygiene. | +| `setup.sh` | Bootstrap script. | + +Several of these were minted from `rsr-template-repo` and describe a project +shape this repo does not have. Treat them as scaffolding, not as instructions. diff --git a/wiki/Contributing.md b/wiki/Contributing.md new file mode 100644 index 0000000..e8a2786 --- /dev/null +++ b/wiki/Contributing.md @@ -0,0 +1,75 @@ + + + + +# Contributing + +## Before you open a PR + +1. Run the three Rust commands from [Home](Home). All three must pass. +2. If you touched a `uses:` line, regenerate `actions.lock` in the same commit + and run `scripts/check-lock-sync.sh`. +3. If you removed or retired a CI check, add or update a row in + `docs/ci/CHECK-DETERMINATIONS.adoc`. Never silence a gate with + `continue-on-error`, `if: false`, or a quiet deletion. +4. Update `TOPOLOGY.adoc` if you changed a component's completion state. + +## House style + +* AsciiDoc (`.adoc`) for repository documentation. SPDX header on every file. +* `MPL-2.0` licence. Palimpsest philosophy. +* Conventional commits: `fix(rust): …`, `docs(ci): …`, `ci: …`. +* No new TypeScript, Python or Go. No npm/bun/yarn/pnpm dependencies. +* `.machine_readable/` is load-bearing — do not restructure it casually. + +## The `REQUIRES_INITIALISATION` gate + +`0-AI-MANIFEST.a2ml` points at `REQUIRES_INITIALISATION.adoc`, which lists +substitution tokens the repo template could not fill because they need a human +decision. Resolve what you legitimately can from evidence; leave the rest. Do +not delete the file to make a gate go green. + +## Editing this wiki + +The wiki is BerryWiki-format. Two ways to work on it: + +**Directly in the GitHub wiki** — fine for prose tweaks. The pages stay plain +Markdown and GitHub renders them natively. + +**From the repo** — preferred for anything reviewable: + +```bash +# wiki/ in this repo is the source of truth +berrywiki check wiki # tree + diagnostics; exit 1 on any error +berrywiki sidebar wiki --write # regenerate _Sidebar.md +``` + +Then push `wiki/` to the wiki remote: + +```bash +git clone https://github.com/hyperpolymath/blocky-writer.wiki.git +cp wiki/*.md blocky-writer.wiki/ +cd blocky-writer.wiki && git add -A && git commit -m "wiki: sync from wiki/" && git push +``` + +The metadata block at the top of each page is what BerryWiki reads. It must be +the **first non-blank content** of the file. Hierarchy comes from the `parent` +id chain, never from the filename; the `--` in filenames is a human-friendly +slug only. `berrywiki check` catches broken links, missing parents, cycles and +duplicate ids. + +Never serve `